1

Тема: AHK: Сохранение Массива в файл

Доброго времени суток!

В этом топике: http://forum.script-coding.com/viewtopi … 418#p48418
нашел вот такой пример кода:

Array := []

Loop 1000           ; добавляем в массив 1000 элементов, которые будут
   Array[A_Index] := A_Index    ; натуральными числами от 1 до 1000
   
MsgBox, % Array.500

Подскажите пожалуйста, можно ли сохранить массив "Array" в файл?
Если да, то покажите пожалуйста пример кода?

AutoHotKey Version: 1.1.09.02
Не спеши, а то успеешь..

2

Re: AHK: Сохранение Массива в файл

Присоединюсь к вопросу, возможно ли конвертировать (то есть без парсинга) массив в base64, и обратно воссоздать его из строки.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

3

Re: AHK: Сохранение Массива в файл

Можно в JSON-строку и обратно.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

4 (изменено: serzh82saratov, 2017-02-19 17:07:20)

Re: AHK: Сохранение Массива в файл

А массив не как отрезок в памяти выглядит, нельзя его получить как бинарные данные?
Вопрос не про JSON, а про массив АНК.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

5

Re: AHK: Сохранение Массива в файл

serzh82saratov пишет:

Вопрос не про JSON, а про массив АНК.

Я про то, что самый простой способ решить эту задачу — превратить AHK-объект в JSON-строку и сохранить в файл. Потом в обратном порядке. Есть функция для парсинга туда и обратно:

JSON := new JSON
MsgBox, % str := JSON.Dump( [{key1: "value1"}, {key2: "value2"}, {key3: "value3"}] )
obj := JSON.Load(str)
for k, v in obj
   for k, v in v
      MsgBox, % k " = " v

/**
 * Lib: JSON.ahk
 *     JSON lib for AutoHotkey.
 * Version:
 *     v2.1.3 [updated 04/18/2016 (MM/DD/YYYY)]
 * License:
 *     WTFPL [http://wtfpl.net/]
 * Requirements:
 *     Latest version of AutoHotkey (v1.1+ or v2.0-a+)
 * Installation:
 *     Use #Include JSON.ahk or copy into a function library folder and then
 *     use #Include <JSON>
 * Links:
 *     GitHub:     - https://github.com/cocobelgica/AutoHotkey-JSON
 *     Forum Topic - http://goo.gl/r0zI8t
 *     Email:      - cocobelgica@gmail.com
 */


/**
 * Class: JSON
 *     The JSON object contains methods for parsing JSON and converting values
 *     to JSON. Callable - NO; Instantiable - YES; Subclassable - YES;
 *     Nestable(via #Include) - NO.
 * Methods:
 *     Load() - see relevant documentation before method definition header
 *     Dump() - see relevant documentation before method definition header
 */
class JSON
{
   /**
    * Method: Load
    *     Parses a JSON string into an AHK value
    * Syntax:
    *     value := JSON.Load( text [, reviver ] )
    * Parameter(s):
    *     value      [retval] - parsed value
    *     text    [in, ByRef] - JSON formatted string
    *     reviver   [in, opt] - function object, similar to JavaScript's
    *                           JSON.parse() 'reviver' parameter
    */
   class Load extends JSON.Functor
   {
      Call(self, ByRef text, reviver:="")
      {
         this.rev := IsObject(reviver) ? reviver : false
      ; Object keys(and array indices) are temporarily stored in arrays so that
      ; we can enumerate them in the order they appear in the document/text instead
      ; of alphabetically. Skip if no reviver function is specified.
         this.keys := this.rev ? {} : false

         static quot := Chr(34), bashq := "\" . quot
              , json_value := quot . "{[01234567890-tfn"
              , json_value_or_array_closing := quot . "{[]01234567890-tfn"
              , object_key_or_object_closing := quot . "}"

         key := ""
         is_key := false
         root := {}
         stack := [root]
         next := json_value
         pos := 0

         while ((ch := SubStr(text, ++pos, 1)) != "") {
            if InStr(" `t`r`n", ch)
               continue
            if !InStr(next, ch, 1)
               this.ParseError(next, text, pos)

            holder := stack[1]
            is_array := holder.IsArray

            if InStr(",:", ch) {
               next := (is_key := !is_array && ch == ",") ? quot : json_value

            } else if InStr("}]", ch) {
               ObjRemoveAt(stack, 1)
               next := stack[1]==root ? "" : stack[1].IsArray ? ",]" : ",}"

            } else {
               if InStr("{[", ch) {
               ; Check if Array() is overridden and if its return value has
               ; the 'IsArray' property. If so, Array() will be called normally,
               ; otherwise, use a custom base object for arrays
                  static json_array := Func("Array").IsBuiltIn || ![].IsArray ? {IsArray: true} : 0
               
               ; sacrifice readability for minor(actually negligible) performance gain
                  (ch == "{")
                     ? ( is_key := true
                       , value := {}
                       , next := object_key_or_object_closing )
                  ; ch == "["
                     : ( value := json_array ? new json_array : []
                       , next := json_value_or_array_closing )
                  
                  ObjInsertAt(stack, 1, value)

                  if (this.keys)
                     this.keys[value] := []
               
               } else {
                  if (ch == quot) {
                     i := pos
                     while (i := InStr(text, quot,, i+1)) {
                        value := StrReplace(SubStr(text, pos+1, i-pos-1), "\\", "\u005c")

                        static tail := A_AhkVersion<"2" ? 0 : -1
                        if (SubStr(value, tail) != "\")
                           break
                     }

                     if (!i)
                        this.ParseError("'", text, pos)

                       value := StrReplace(value,  "\/",  "/")
                     , value := StrReplace(value, bashq, quot)
                     , value := StrReplace(value,  "\b", "`b")
                     , value := StrReplace(value,  "\f", "`f")
                     , value := StrReplace(value,  "\n", "`n")
                     , value := StrReplace(value,  "\r", "`r")
                     , value := StrReplace(value,  "\t", "`t")

                     pos := i ; update pos
                     
                     i := 0
                     while (i := InStr(value, "\",, i+1)) {
                        if !(SubStr(value, i+1, 1) == "u")
                           this.ParseError("\", text, pos - StrLen(SubStr(value, i+1)))

                        uffff := Abs("0x" . SubStr(value, i+2, 4))
                        if (A_IsUnicode || uffff < 0x100)
                           value := SubStr(value, 1, i-1) . Chr(uffff) . SubStr(value, i+6)
                     }

                     if (is_key) {
                        key := value, next := ":"
                        continue
                     }
                  
                  } else {
                     value := SubStr(text, pos, i := RegExMatch(text, "[\]\},\s]|$",, pos)-pos)

                     static number := "number", integer :="integer"
                     if value is %number%
                     {
                        if value is %integer%
                           value += 0
                     }
                     else if (value == "true" || value == "false")
                        value := %value% + 0
                     else if (value == "null")
                        value := ""
                     else
                     ; we can do more here to pinpoint the actual culprit
                     ; but that's just too much extra work.
                        this.ParseError(next, text, pos, i)

                     pos += i-1
                  }

                  next := holder==root ? "" : is_array ? ",]" : ",}"
               } ; If InStr("{[", ch) { ... } else

               is_array? key := ObjPush(holder, value) : holder[key] := value

               if (this.keys && this.keys.HasKey(holder))
                  this.keys[holder].Push(key)
            }
         
         } ; while ( ... )

         return this.rev ? this.Walk(root, "") : root[""]
      }

      ParseError(expect, ByRef text, pos, len:=1)
      {
         static quot := Chr(34), qurly := quot . "}"
         
         line := StrSplit(SubStr(text, 1, pos), "`n", "`r").Length()
         col := pos - InStr(text, "`n",, -(StrLen(text)-pos+1))
         msg := Format("{1}`n`nLine:`t{2}`nCol:`t{3}`nChar:`t{4}"
         ,     (expect == "")     ? "Extra data"
             : (expect == "'")    ? "Unterminated string starting at"
             : (expect == "\")    ? "Invalid \escape"
             : (expect == ":")    ? "Expecting ':' delimiter"
             : (expect == quot)   ? "Expecting object key enclosed in double quotes"
             : (expect == qurly)  ? "Expecting object key enclosed in double quotes or object closing '}'"
             : (expect == ",}")   ? "Expecting ',' delimiter or object closing '}'"
             : (expect == ",]")   ? "Expecting ',' delimiter or array closing ']'"
             : InStr(expect, "]") ? "Expecting JSON value or array closing ']'"
             :                      "Expecting JSON value(string, number, true, false, null, object or array)"
         , line, col, pos)

         static offset := A_AhkVersion<"2" ? -3 : -4
         throw Exception(msg, offset, SubStr(text, pos, len))
      }

      Walk(holder, key)
      {
         value := holder[key]
         if IsObject(value) {
            for i, k in this.keys[value] {
               ; check if ObjHasKey(value, k) ??
               v := this.Walk(value, k)
               if (v != JSON.Undefined)
                  value[k] := v
               else
                  ObjDelete(value, k)
            }
         }
         
         return this.rev.Call(holder, key, value)
      }
   }

   /**
    * Method: Dump
    *     Converts an AHK value into a JSON string
    * Syntax:
    *     str := JSON.Dump( value [, replacer, space ] )
    * Parameter(s):
    *     str        [retval] - JSON representation of an AHK value
    *     value          [in] - any value(object, string, number)
    *     replacer  [in, opt] - function object, similar to JavaScript's
    *                           JSON.stringify() 'replacer' parameter
    *     space     [in, opt] - similar to JavaScript's JSON.stringify()
    *                           'space' parameter
    */
   class Dump extends JSON.Functor
   {
      Call(self, value, replacer:="", space:="")
      {
         this.rep := IsObject(replacer) ? replacer : ""

         this.gap := ""
         if (space) {
            static integer := "integer"
            if space is %integer%
               Loop, % ((n := Abs(space))>10 ? 10 : n)
                  this.gap .= " "
            else
               this.gap := SubStr(space, 1, 10)

            this.indent := "`n"
         }

         return this.Str({"": value}, "")
      }

      Str(holder, key)
      {
         value := holder[key]

         if (this.rep)
            value := this.rep.Call(holder, key, ObjHasKey(holder, key) ? value : JSON.Undefined)

         if IsObject(value) {
         ; Check object type, skip serialization for other object types such as
         ; ComObject, Func, BoundFunc, FileObject, RegExMatchObject, Property, etc.
            static type := A_AhkVersion<"2" ? "" : Func("Type")
            if (type ? type.Call(value) == "Object" : ObjGetCapacity(value) != "") {
               if (this.gap) {
                  stepback := this.indent
                  this.indent .= this.gap
               }

               is_array := value.IsArray
            ; Array() is not overridden, rollback to old method of
            ; identifying array-like objects. Due to the use of a for-loop
            ; sparse arrays such as '[1,,3]' are detected as objects({}). 
               if (!is_array) {
                  for i in value
                     is_array := i == A_Index
                  until !is_array
               }

               str := ""
               if (is_array) {
                  Loop, % value.Length() {
                     if (this.gap)
                        str .= this.indent
                     
                     v := this.Str(value, A_Index)
                     str .= (v != "") ? v . "," : "null,"
                  }
               } else {
                  colon := this.gap ? ": " : ":"
                  for k in value {
                     v := this.Str(value, k)
                     if (v != "") {
                        if (this.gap)
                           str .= this.indent

                        str .= this.Quote(k) . colon . v . ","
                     }
                  }
               }

               if (str != "") {
                  str := RTrim(str, ",")
                  if (this.gap)
                     str .= stepback
               }

               if (this.gap)
                  this.indent := stepback

               return is_array ? "[" . str . "]" : "{" . str . "}"
            }
         
         } else ; is_number ? value : "value"
            return ObjGetCapacity([value], 1)=="" ? value : this.Quote(value)
      }

      Quote(string)
      {
         static quot := Chr(34), bashq := "\" . quot

         if (string != "") {
              string := StrReplace(string,  "\",  "\\")
            ; , string := StrReplace(string,  "/",  "\/") ; optional in ECMAScript
            , string := StrReplace(string, quot, bashq)
            , string := StrReplace(string, "`b",  "\b")
            , string := StrReplace(string, "`f",  "\f")
            , string := StrReplace(string, "`n",  "\n")
            , string := StrReplace(string, "`r",  "\r")
            , string := StrReplace(string, "`t",  "\t")

            static rx_escapable := A_AhkVersion<"2" ? "O)[^\x20-\x7e]" : "[^\x20-\x7e]"
            while RegExMatch(string, rx_escapable, m)
               string := StrReplace(string, m.Value, Format("\u{1:04x}", Ord(m.Value)))
         }

         return quot . string . quot
      }
   }

   /**
    * Property: Undefined
    *     Proxy for 'undefined' type
    * Syntax:
    *     undefined := JSON.Undefined
    * Remarks:
    *     For use with reviver and replacer functions since AutoHotkey does not
    *     have an 'undefined' type. Returning blank("") or 0 won't work since these
    *     can't be distnguished from actual JSON values. This leaves us with objects.
    *     Replacer() - the caller may return a non-serializable AHK objects such as
    *     ComObject, Func, BoundFunc, FileObject, RegExMatchObject, and Property to
    *     mimic the behavior of returning 'undefined' in JavaScript but for the sake
    *     of code readability and convenience, it's better to do 'return JSON.Undefined'.
    *     Internally, the property returns a ComObject with the variant type of VT_EMPTY.
    */
   Undefined[]
   {
      get {
         static empty := {}, vt_empty := ComObject(0, &empty, 1)
         return vt_empty
      }
   }

   class Functor
   {
      __Call(method, ByRef arg, args*)
      {
      ; When casting to Call(), use a new instance of the "function object"
      ; so as to avoid directly storing the properties(used across sub-methods)
      ; into the "function object" itself.
         if IsObject(method)
            return (new this).Call(method, arg, args*)
         else if (method == "")
            return (new this).Call(arg, args*)
      }
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

6

Re: AHK: Сохранение Массива в файл

serzh82saratov пишет:

А массив не как отрезок в памяти выглядит, нельзя его получить как бинарные данные?
Вопрос не про JSON, а про массив АНК.

Если массив создать через ComObjArray, то там, в принципе, можно получить адрес данных в памяти и сохранить их в бинарном виде. А может, для этого и какие-то API-функции есть. Но массив АНК более сложная конструкция и там элементы не обязаны идти один за другим, а где угодно могут находиться.

7

Re: AHK: Сохранение Массива в файл

Спасибо.

AutoHotKey Version: 1.1.09.02
Не спеши, а то успеешь..

8

Re: AHK: Сохранение Массива в файл

Пример:

;=============== ======================================================
;=============== Основные блоки 
;=======================================================================
Time_Limits_ := ""
Win_List_Limits_ := ""
Time_Count_ := ""
;=======================================================================

;=============== Начальное значение для Time_Limits := [] 
;=============== В процессе работы, кол-во переменных Time_Limits_[A_Index] может менятся +/-
Time_Limits_1 := "600", Time_Limits_2 := "800"
Time_Limits_3 := "850", Time_Limits_4 := "450"
;=============== Начальное значение для Win_List_Limits := []
;=============== В процессе работы, кол-во переменных Win_List_Limits_[A_Index] может менятся +/-
Win_List_Limits_1 = 
(
Abc
Cba
SSD
)
Win_List_Limits_2 =
(
jjg
ffd
xdr
)
;=============== Начальное значение для Time_Count := []
;=============== В процессе работы, кол-во переменных Time_Count_[A_Index] может менятся +/-
Time_Count_1 := "45", Time_Count_2 := "74", Time_Count_3 := "19"
Time_Count_4 := "24", Time_Count_5 := "17"
;=================================================================

Loop
{
	If !(Time_Limits_%A_Index%) {
		loop_List .= "|`n"
		break
	}
	loop_List .= "Time_Limits_" A_Index ":" Time_Limits_%A_Index% "`n"
}

Loop
{
	If !(Win_List_Limits_%A_Index%) {
		loop_List .= "|`n"
		break
	}
	loop_List .= "Win_List_Limits_" A_Index ":" Win_List_Limits_%A_Index% "`n"
}

Loop
{
	If !(Time_Count_%A_Index%) {
		loop_List .= "|`n"
		break
	}
	loop_List .= "Time_Count_" A_Index ":" Time_Count_%A_Index% "`n"
}

MsgBox, % loop_List

;  = перед зыкрытием скрипта - записываем в файл....
;~ FileAppend, % loop_List, % File_Name

;  = После запуска
;~ FileRead, loop_List, % File_Name

Я так понимаю, что для моей задачи, массивы вовсе не нужны? Проще использовать множество пронумерованных переменных?

AutoHotKey Version: 1.1.09.02
Не спеши, а то успеешь..

9

Re: AHK: Сохранение Массива в файл

То чувство, когда ничего тут не понимаешь .

10

Re: AHK: Сохранение Массива в файл

Массивы в каком-то смысле и есть пронумерованные переменные. Правда можно вместо нумеров использовать имена:

Array := {KeyA: ValueA, KeyB: ValueB, ..., KeyZ: ValueZ}

Чтобы понять, что лучше подходит, необходимо знать поставленную задачу.

11

Re: AHK: Сохранение Массива в файл

YMP пишет:

Если массив создать через ComObjArray, то там, в принципе, можно получить адрес данных в памяти и сохранить их в бинарном виде.

А создать массив из таких данных получится?

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

12

Re: AHK: Сохранение Массива в файл

serzh82saratov пишет:

А массив не как отрезок в памяти выглядит, нельзя его получить как бинарные данные?

Можно:
https://autohotkey.com/boards/viewtopic.php?p=23832

13

Re: AHK: Сохранение Массива в файл

Malcev как всегда нашёл.
Там дальше в теме, ещё через WM_COPYDATA массивы "перекидывают".

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

14 (изменено: YMP, 2017-02-20 06:17:31)

Re: AHK: Сохранение Массива в файл

serzh82saratov пишет:

А создать массив из таких данных получится?

Да, можно ведь сохранить и дескриптор массива, т.е. структуру SAFEARRAY.

15

Re: AHK: Сохранение Массива в файл

Пример, который нашёл Malcev интересный, но если использовать JSON, мы получим в файле читаемый текст.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

16

Re: AHK: Сохранение Массива в файл

YMP а пример сложный получится?

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

17

Re: AHK: Сохранение Массива в файл

Так сходу не смогу написать. Есть там свои тонкости. Как минимум, строки нужно тоже сохранять где-то, т.к., по идее, в самом массиве только указатели на них. При восстановлении для них память нужно запрашивать не абы как, а через SysAllocString и т.п. функции. Флаги ещё там какие-то, с которыми тоже надо разбираться.

18 (изменено: migomigo, 2017-02-21 21:42:42)

Re: AHK: Сохранение Массива в файл

ypppu

ypppu пишет:

Чтобы понять, что лучше подходит, необходимо знать поставленную задачу.

В скрипте 3 массива:

Time_Counts_[]/Win_Limits_[]/Time_Limits_ в 1-ну переменную: "loop_List_Fold"

Их необходимо сохранить в 1 переменную.
Далее, после перезагрузки компьютера, необходимо их считать,  из файла распределить в 3 массива на места, для дальнейшей оброботки скриптом.

Вот попытка, но что-то не так:

+ открыть спойлер

;============================  Набор данных..
;============================
;============================


Time_Limits_1 := A_YEAR "." A_MM "." A_DD
;-----------------------------------------------------------
;~ Time_Limits_1 := Time_Mem_1    ;;;;;;; --------------------- 1.1


Time_Limits_2 := "10800000"   ; ===================== [ Допустимое время работы 3 часа] ==============
;================ [ 10 800 000 = 3 час. ] / [ 7 200 000 = 2 час. ] / [ 3 600 000 = 1 час. ] / [ 1 800 000 = 30 мин. ]
;-----------------------------------------------------------
;~ Time_Limits_2 := Time_Limit_1 ;;;;;;; ---------------------- 1.2

Time_Limits_3 := "19"
;-----------------------------------------------------------
;~ Time_Limits_3 := Time_Count_1 ;;;;-------------------------- 1.3

Time_Limits_4 := "18"              ; ====================== [ Начало разрешенного времени - кратно часам   для " T_Check_Perm(T_Perm_B, T_Perm_S)  " ] ==
;-----------------------------------------------------------
;~ Time_Limits_4 := T_Perm_B  ;;;;----------------------------- 1.4

Time_Limits_5 := "22"              ; ======================= [ Конец разрешенного времени - кратно часам ] =================
;-----------------------------------------------------------
;~ Time_Limits_5 := T_Perm_S ;;;;------------------------------ 1.5

Time_Limits_6 := "188"    ;
;-----------------------------------------------------------
;~ Time_Limits_6 := Time_Limit_B ;;;;-------------------------- 1.6

Time_Limits_7 := "1754"
;-----------------------------------------------------------
;~ Time_Limits_7 := Time_Limit_H ;;;;-------------------------- 1.7

Time_Limits_8 := A_YEAR ":" A_MM ":" A_DD
;-----------------------------------------------------------
;~ Time_Limits_8 := Time_Mem_2    ;;;;;;; --------------------- 1.8

Time_Limits_9 := "10800000"   ; ===================== [ Допустимое время работы ] ==============
;================ [ 10 800 000 = 3 час. ] / [ 7 200 000 = 2 час. ] / [ 3 600 000 = 1 час. ] / [ 1 800 000 = 30 мин. ]
;~ Time_Limits_9 := Time_Limit_Mn_Fr_H ;;;;;;; ---------------- 1.9


Win_Limits_1 = 
(
В Контакте
Home - ROBLOX
ok.ru
http://worldoftanks.ru
ROBLOX
)
;----------------------------------------------------------------
;~ Win_Limits_1 := Win_Name_Limit_1 ;;;;;;;; ----------------------- 2.1

Win_Limits_2 = 
(
WoT Client
)
;-----------------------------------------------------------------
;~ Win_Limits_2 := Win_Name_Limit_2 ;;;;;---------------------------- 2.2
;

;-----------------------------------------------------------------
Time_Counts_1 := "1"
;-----------------------------------------------------------------
;~ Time_Counts_1 := Time_Count_2 := "0" ;;;;;------------------------ 3.1

;============================
;============================
;============================

Loop
{
	If !(Time_Limits_%A_Index%)
		break
	Befo_loop_List_Extract_Report .= "Time_Limits_" A_Index ":" Time_Limits_%A_Index% "`n"
}
Loop
{
	If !(Win_Limits_%A_Index%)
		break
	Befo_loop_List_Extract_Report .= "Win_Limits" A_Index ":" Win_Limits_%A_Index% "`n"
}
Loop
{
	If !(Time_Counts_%A_Index%)
		break
	Befo_loop_List_Extract_Report .= "Time_Counts_" A_Index ":" Time_Counts_%A_Index% "`n"
}



; =========================================================
; =============================== Сохраняем 3 массива Time_Counts_[]/Win_Limits_[]/Time_Limits_ в 1-ну переменную: "loop_List_Fold"

Loop
{
	If !(Time_Limits_%A_Index%) {
		break
	}
	loop_List_Fold .= "Time_Limits_" A_Index "\" Time_Limits_%A_Index%
	If (Time_Limits_%A_Index%) {
	loop_List_Fold .= "|"
	}
}
Loop
{
	If !(Win_Limits_%A_Index%) {
		break
	}
	loop_List_Fold .= "Win_Limits_" A_Index "\" Win_Limits_%A_Index%
	If (Win_Limits_%A_Index%) {
	loop_List_Fold .= "|"
	}
}
Loop
{
	If !(Time_Counts%A_Index%) {
		Time_Counts%A_Index% := "..."
		loop_List_Fold .= Time_Counts%A_Index%
		break
	}
	loop_List_Fold .= "Time_Counts" A_Index "\" Time_Counts%A_Index%
	If (Time_Counts%A_Index%) {
	loop_List_Fold .= "|"
	}
}
;==================================================================================================




; ==================================
; ================= Очищаем 3 массива
Loop
{
	If !(Time_Limits_%A_Index%)
		break
	Time_Limits_%A_Index% := ""
}
Loop
{
	If !(Win_Limits_%A_Index%)
		break
	Win_Limits_%A_Index% := ""
}
Loop
{
	If !(Time_Counts_%A_Index%)
		break
	Time_Counts_%A_Index% := ""
}
;============================================================================================




;============================================  Извлекаем 3 массива из переменной.

TLC := "", TCC := "", WLC := "", loop_List_Extract := ""
Loop, Parse, loop_List_Fold, `|
{
	Loop, Parse, A_LoopField, `\
	{
		If !A_LoopField
			continue
		if InStr(A_LoopField, "Time_Limits_")
		{
			TLC++
			Time_Limits_%TLC% := RegExReplace(A_LoopField, ".+\:(\d+)", "$1")
			loop_List_Extract .= Time_Limits_%TLC% "|"
		}

		if InStr(A_LoopField, "Win_Limits_")
		{
			WLC++
			Win_Limits_%WLC% := RegExReplace(A_LoopField, "^\w+:")
			loop_List_Extract .= Win_Limits_%WLC% "|"
		}

		if InStr(A_LoopField, "Time_Counts_")
		{
			TCC++
			Time_Counts_%TCC% := RegExReplace(A_LoopField, "^\w+:")
			loop_List_Extract .= Time_Counts_%TCC% "|"
		}
	}
}



; ==============================================   Сравниваем что получилось
Loop
{
	If !(Time_Limits_%A_Index%)
		break
	loop_List_Extract_Report .= "Time_Limits_" A_Index ":" Time_Limits_%A_Index% "`n"
}
Loop
{
	If !(Win_Limits_%A_Index%)
		break
	loop_List_Extract_Report .= "Win_Limits" A_Index ":" Win_Limits_%A_Index% "`n"
}
Loop
{
	If !(Time_Counts_%A_Index%)
		break
	loop_List_Extract_Report .= "Time_Counts_" A_Index ":" Time_Counts_%A_Index% "`n"
}



Gui, add, text, cRed, Запарсили массивы
Gui, add, text,, % Befo_loop_List_Extract_Report
Gui, add, text, cRed, Распарсили массивы
Gui, add, text,, % loop_List_Extract_Report
Gui, Show, 
return

GuiClose:
ExitApp
AutoHotKey Version: 1.1.09.02
Не спеши, а то успеешь..

19

Re: AHK: Сохранение Массива в файл

А можно простой пример? Отдельно названия массивов, отдельно содержимое массивов? Штуки три достаточно.
Длинный код не понятно что демонстрирует. Кстати нужно его оформить тегом "code".

20

Re: AHK: Сохранение Массива в файл

YMP
Если код получается также сложен, как в примере HotKeyIt, то видимо нет смысла...

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

21

Re: AHK: Сохранение Массива в файл

https://autohotkey.com/docs/objects/File.htm
RawRead
RawWrite
Seek

22 (изменено: migomigo, 2017-02-22 02:34:39)

Re: AHK: Сохранение Массива в файл

Я то думал что упростил пример..
Попробую переиначить, выхода нет, так как на кону здоровая психика ребенка!

Офтоп:
На этот форум меня привели игры. Попытка получить незначительное преимущество на соревнованиях (2009г.)..

Теперь, спустя годы, (2017г.)вернулся на этот форму работая над скриптом для засчитаны ребенка от игор..  )))

AutoHotKey Version: 1.1.09.02
Не спеши, а то успеешь..

23 (изменено: migomigo, 2017-02-22 04:00:54)

Re: AHK: Сохранение Массива в файл

Всего 3 массива.

Массив №1:
В нем данные, это цыфры, время или даты. Могут быть разделены точкой или двоеточием.

Time_Limits_[3]
	Time_Limits_1 := "1570006"
	Time_Limits_2 := "10:30"
	Time_Limits_3 := "2017.02.23"

Массив №2:
В нем данные, это ключевые слова определяющие активное приложение, страничку интернета и т.д.. Может быть что угодно, и написно с новой строчки:

Win_Counts_[2]
	Win_Counts_1 := "http://worldoftanks.ru" "`n" "Home - ROBLOX" "`n" "ok.ru"
	Win_Counts_2 := "ROBLOX" "`n" "WoT Client" "`n"

Массив №3:
В нем данные, это цыфры, без каких либо иных знаков

Time_Counts_[3]
	Time_Counts_1 := "12"
	Time_Counts_2 := "3600000"
	Time_Counts_3 := "65470"

Количество строк каждого массива может изменяться в процессе работы скрипта..
Например при запуске скрипта:

Time_Counts_[3]
Win_Counts_[2]
Win_Counts_[10]

После завершения работы скрипта, может выглядеть так:

Time_Counts_[15]
Win_Counts_[4]
Win_Counts_[8]

Задача, запарсить это все в 1 переменную для сохранения в файл.



Дальше, распарсить и обратно разсовать по своим строчкам в свои массивы, при это сохранить очередность.

AutoHotKey Version: 1.1.09.02
Не спеши, а то успеешь..

24 (изменено: migomigo, 2017-02-22 03:34:16)

Re: AHK: Сохранение Массива в файл

Как запаковать 3 массива, я примерно понимаю.

+ открыть спойлер
	Time_Limits_1 := "1570006"
	Time_Limits_2 := "10:30"
	Win_Counts_1 := "http://worldoftanks.ru" "`n" "Home - ROBLOX" "`n" "ok.ru"
	Win_Counts_2 := "ROBLOX" "`n" "WoT Client" "`n"
	Time_Counts_1 := "12"
	Time_Counts_2 := "3600000"
	
	
Loop ; Последовательно записываем в переменную "array_block .=" массив Time_Limits_[] разделяя строки "|и*"
{
	If !(Time_Limits_%A_Index%)
		break
	array_block .= "Time_Limits_" A_Index "|" Time_Limits_%A_Index% "*"
}

Loop  ; Последовательно записываем в переменную "array_block .=" массив Win_Limits_[] разделяя строки "|и*"
{
	If !(Win_Counts_%A_Index%)
		break
	array_block .= "Win_Counts_" A_Index "|" Win_Counts_%A_Index% "*"
}
Loop   ; Последовательно записываем в переменную "array_block .=" массив Time_Counts_[] разделяя строки "|и*"
{
	If !(Time_Counts_%A_Index%) {
		Time_Counts_%A_Index% := "..."
		array_block .= Time_Counts_%A_Index%
		break
	}
	array_block .= "Time_Counts_" A_Index "|" Time_Counts_%A_Index% "*"
}
	
Gui, add, text, cRed, Запарсили массивы
Gui, add, text,, % array_block
Gui, Show, 
return

GuiClose:
ExitApp

А вот правильно извлечь запакованное - не выходит..

AutoHotKey Version: 1.1.09.02
Не спеши, а то успеешь..

25

Re: AHK: Сохранение Массива в файл

Ну так FileAppend что б записать, FileRead и Loop, Parse что б считать. Берешь уникальный разделитель и вставляешь между элементами массива, потом ложишь все это на диск. Обратно – считываешь и парсишь. Если массивов много то можно через несколько файлов работать под отдельные массивы – так проще.