SHARE
TWEET

array.bat

a guest Sep 16th, 2010 1,474 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. @ECHO off
  2. rem Включаем отложеную подстановку переменных (ENABLEDELAYEDEXPANSION)
  3. rem Нужно для того, чтобы переменные виже !var! подставлялись в момент выполнения
  4. rem В противном случае внутри блоков if переменные нельзя будет менять
  5. rem Включием расширенную обработку комманд (ENABLEEXTENSIONS)
  6. rem В частности для того, чтобы можно было использовать параметр /I в if.
  7. setlocal ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
  8.  
  9.  
  10. echo Создание массива А и вывод:
  11. call :array new A "'one','two','three','foo','bar'"
  12. call :array dump A
  13. echo.
  14. echo Добавление к массиву A элементов из набора
  15. call :array add A "'first line' 'Вторая строка' 12 54" !
  16. call :array dump A
  17. echo.
  18. echo Поиск строки BAR
  19. call :array find A "BAR" i
  20. echo Найдено в позиции !_l!
  21. echo.
  22. echo Удаление элементов 3 5 8
  23. call :array del A "3 5 8"
  24. call :array dump A
  25. echo.
  26. echo Удаление элемента two
  27. call :array find A Two i
  28. call :array del A !_l!
  29. call :array dump A
  30. echo.
  31. echo Сортировка массива
  32. call :array sort A
  33. call :array dump A
  34.  
  35.  
  36.  
  37.  
  38. goto :eof
  39.  
  40. goto :exit
  41.  
  42. rem =====  Arrays =====
  43. rem Важно помнить, что после каждого вызова функции удаляются все переменные, начинающиеся на __
  44. :array
  45.         rem Сохранение аргументов в локальных переменных
  46.         rem чтобы можно было обращать отложенным методом !__1!
  47.         rem ~ - убрать кавычки
  48.         set __1=%~1
  49.         set __2=%~2
  50.         set __3=%~3
  51.         set __4=%~4
  52.         set __5=%~5
  53.         set __6=%~6
  54.  
  55.        
  56.         rem == create ==
  57.         rem Создание массива
  58.         rem call :array create имя_массива [размер=0] [начальные значения=0]
  59.         if /I "!__1!"=="create" (
  60.  
  61.                 rem Имя массива
  62.                 if "!__2!"=="" (
  63.                         echo Не указано имя массива
  64.                         goto :eof
  65.                 )
  66.                 set _name=array_!__2!
  67.                
  68.                 rem Размер
  69.                 set /a _count=0
  70.                 if not "!__3!"=="" (
  71.                         set /a _count = !__3!
  72.                 )
  73.                
  74.                 rem Начальные значения
  75.                 set _defval=0
  76.                 if not "!__4!"=="" (
  77.                         set _defval=!__4!
  78.                 )
  79.                
  80.                 rem Удаление массива, если существует c таким же именем
  81.                 rem Можно было не удалять все переменные, а только оставшиеся после перезаписи, но может быть как-нибудь потом
  82.                 call :array_del_ifdef !__2!
  83.                
  84.                 set /a __maxindex=!_count!-1
  85.                
  86.                 for /l %%i in (0,1,!__maxindex!) do set !_name!_%%i=!_defval!
  87.                 set /a !_name!_count = !_count!
  88.                
  89.                 set _name=
  90.                 set _count=
  91.                 set _defval=
  92.                
  93.         rem == new ==
  94.         rem Создание массива из набора значений
  95.         rem call :array new имя_массива "знач1, знач2, 'строка' ..."
  96.         ) else if /I "!__1!"=="new" (
  97.        
  98.                 rem Имя массива
  99.                 if "!__2!"=="" (
  100.                         echo Не указано имя массива
  101.                         goto :eof
  102.                 )
  103.                
  104.                 if "!__3!"=="" (
  105.                         echo Не указан набор значений
  106.                         goto :eof
  107.                 )
  108.                
  109.  
  110.  
  111.                 rem Заменяем одинарные кавычки на двойные
  112.                 set _elems=!__3:'="!
  113.                
  114.                 set _name=array_!__2!
  115.                
  116.                 rem Удаление массива, если существует c таким же именем
  117.                 call :array_del_ifdef !__2!
  118.                
  119.                 rem Создаем последовательно каждый элемент и присваиваем значение
  120.                 set /a __i=0
  121.                 for %%i in (!_elems!) do (
  122.                         rem ~ - убираем кавычки, которые необходимя просто для группировки
  123.                         set !_name!_!__i!=%%~i
  124.                         set /a __i+=1
  125.                 )
  126.                
  127.                 set /a !_name!_count=!__i!
  128.                 set _elems=
  129.                
  130.         rem == get ==
  131.         rem Получение элемента массива (сохранение в переменную)
  132.         rem call :array get имя_массива [index=0] [имя_целевой_переменной=_l]
  133.         rem Если индекс отрицательный, то он считается с конца (-1 - последний, -2 - предпоследний и т.д.)
  134.         ) else if /I "!__1!"=="get" (
  135.  
  136.                 rem Имя массива
  137.                 if "!__2!"=="" (
  138.                         echo Не указано имя массива
  139.                         goto :eof
  140.                 )
  141.                 set __name=array_!__2!
  142.                
  143.                 rem Проверка существования массива
  144.                 call :array_notdefined !__2! __errors
  145.                
  146.                 rem Если есть ошибки, то выходим
  147.                 if not !__errors!==0 goto :eof
  148.                
  149.                 rem Индекс элемента
  150.                 set /a __i = 0
  151.                 if not "!__3!"=="" (
  152.                         set /a __i = !__3!
  153.                 )
  154.  
  155.                 rem Если индекс отрицательный, то считаем с конца
  156.                 if !__i! LSS 0 (
  157.                         rem Получаем размер
  158.                         call :set __count !__name!_count
  159.                         set /a __i=!__count!+!__i!
  160.                 )
  161.                
  162.  
  163.                 rem Имя переменной, содержащей значение элемента
  164.                 set __target=!__name!_!__i!
  165.                
  166.                 rem Проверка существования элемента
  167.                 if not defined !__target! (
  168.                         echo В массиве !__2! нет элемента с индексом !__i!
  169.                         goto :eof
  170.                 )
  171.                
  172.                 rem Записываем значение элемента во временную переменную
  173.                 call :set __value !__target!
  174.                 set __var=_l
  175.                 if not "!__4!"=="" (
  176.                         set __var=!__4!
  177.                 )
  178.                
  179.                 rem Записываем в целевую
  180.                 call :set !__var! __value
  181.        
  182.        
  183.        
  184.         rem == echo ==
  185.         rem Вывод значения элемента на экран
  186.         ) else if /I "!__1!"=="echo" (
  187.                
  188.                 call :array get !__2! !__3! _tmpval
  189.                 if not "!_tmpval!"=="" (
  190.                         echo !_tmpval!
  191.                 )
  192.                 set _tmpval=
  193.                
  194.  
  195.         rem == list ==
  196.         rem Вывод значений списком. Может быть полезно при перенаправлении вывода
  197.         rem call :array list имя_массива
  198.         rem Пример: call :array list myArr > array.txt  - сохраняет текущий массив в файт array.txt
  199.         rem Для сохранения в кодировке cp1251 используйте save
  200.         ) else if /I "!__1!"=="list" (
  201.                
  202.                 rem Имя массива
  203.                 if "!__2!"=="" (
  204.                         echo Не указано имя массива
  205.                         goto :eof
  206.                 )
  207.                
  208.                
  209.                 rem Проверка существования массива
  210.                 call :array_notdefined !__2! __errors
  211.                
  212.                 rem Если есть ошибки, то выходим
  213.                 if not !__errors!==0 goto :eof
  214.                
  215.                 set __name=array_!__2!
  216.                
  217.                 rem Получаем размер
  218.                 call :set __count !__name!_count
  219.                 set /a __maxindex=!__count!-1
  220.                
  221.                 rem Вывод значений
  222.                 for /l %%i in (0,1,!__maxindex!) do (
  223.                         call :set __value !__name!_%%i
  224.                         echo !__value!
  225.                 )
  226.        
  227.         rem == save ==
  228.         rem Сохраняет массив в указанный файл в кодировке cp1251
  229.         rem call :array save имя_массива имя_файла
  230.         ) else if /i "!__1!"=="save" (
  231.        
  232.                 rem Имя файла
  233.                 if "!__3!"=="" (
  234.                         echo Не указано имя файла
  235.                         goto :eof
  236.                 )
  237.                
  238.                 rem Парсим вывод команды chcp, ищим номер кодовой страницы и запаминаем
  239.                 for /f "usebackq tokens=2 delims=:" %%i in (`chcp`) do set /a _pageset=%%i
  240.                
  241.                 rem Меняем кодовую страницу на 1251
  242.                 chcp 1251>nul
  243.                 rem Перенаправляем вывод list в файл
  244.                 call :array list !__2! > !__3!
  245.                 rem Возвращаем кодовую страницу
  246.                 chcp !_pageset!>nul
  247.                
  248.                
  249.                 set _pageset=
  250.                
  251.                
  252.         rem == load ==
  253.         rem Чтение в массив из файла, с кодировкой cp1251
  254.         rem call :array load имя_массива имя_файла
  255.         ) else if /i "!__1!"=="load" (
  256.                 rem Имя массива
  257.                 if "!__2!"=="" (
  258.                         echo Не указано имя массива
  259.                         goto :eof
  260.                 )
  261.                
  262.                 rem Имя файла
  263.                 if "!__3!"=="" (
  264.                         echo Не указано имя файла
  265.                         goto :eof
  266.                 )
  267.                
  268.                 if not exist "!__3!" (
  269.                         echo Файл !__3! не найден
  270.                         goto :eof
  271.                 )
  272.                
  273.                 set _file=!__3!
  274.                 set _shortname=!__2!
  275.                
  276.                
  277.                 rem Удаляем массив, если сущестует
  278.                 call :array_del_ifdef !__2!
  279.  
  280.                 rem Парсим вывод команды chcp, ищим номер кодовой страницы и запаминаем
  281.                 for /f "usebackq tokens=2 delims=:" %%i in (`chcp`) do set /a _pageset=%%i
  282.                
  283.                 rem Меняем кодовую страницу на 1251
  284.                 chcp 1251>nul
  285.                
  286.                 rem Вносим каждую строку файла в массив
  287.                 rem Используем call, чтобы выполнялось в новой кодовой странице
  288.                 call :array load_unsafe !_shortname! !_file!
  289.                                
  290.                 rem Возвращаем кодовую страницу
  291.                 chcp !_pageset!>nul
  292.  
  293.                 set _name=
  294.                 set _file=
  295.                 set _pageset=
  296.                 set _shortname=
  297.                
  298.         rem == load_unsafe ==
  299.         rem Чтение массива из файла небезопасное.
  300.         rem Нет проверок, нет удаления существующего массива, что ведёт к засорению памяти
  301.         rem Используется при load
  302.         ) else if /I "!__1!"=="load_unsafe" (
  303.                
  304.                 set __i=0
  305.                 rem Вносим каждую строку файла в массив
  306.                 for /f "tokens=*" %%i in (!__3!) do (
  307.                         set array_!__2!_!__i!=%%i
  308.                         set /a __i+=1
  309.                 )
  310.                 set array_!__2!_count=!__i!
  311.                
  312.  
  313.         rem == count ==
  314.         rem Количество элементов в массиве
  315.         rem call :array count имя_массива [имя_целевой_переменной=_l]
  316.         ) else if /I "!__1!"=="count" (
  317.        
  318.        
  319.                 rem Имя массива
  320.                 if "!__2!"=="" (
  321.                         echo Не указано имя массива
  322.                         goto :eof
  323.                 )
  324.                
  325.                
  326.                 rem Проверка существования массива
  327.                 call :array_notdefined !__2! __errors
  328.                
  329.                 rem Если есть ошибки, то выходим
  330.                 if not !__errors!==0 goto :eof
  331.                
  332.                 set __name=array_!__2!
  333.                
  334.                 rem Имя целевой переменной
  335.                 set __var=_l
  336.                 if not "!__3!"=="" (
  337.                         set __var=!__3!
  338.                 )
  339.                
  340.                 rem Записываем в целевую
  341.                 call :set !__var! !__name!_count
  342.                
  343.         rem == dump ==
  344.         rem Вывод массива на экран
  345.         rem call :array dump имя_массива
  346.         ) else if /I "!__1!"=="dump" (
  347.        
  348.                 rem Имя массива
  349.                 if "!__2!"=="" (
  350.                         echo Не указано имя массива
  351.                         goto :eof
  352.                 )
  353.                
  354.                
  355.                 rem Проверка существования массива
  356.                 call :array_notdefined !__2! __errors
  357.                
  358.                 rem Если есть ошибки, то выходим
  359.                 if not !__errors!==0 goto :eof
  360.                
  361.                 set __name=array_!__2!
  362.                
  363.                 rem Получаем размер
  364.                 call :set __count !__name!_count
  365.                 set /a __maxindex=!__count!-1
  366.                
  367.                 echo array[!__count!]: !__2!
  368.                 if !__count!==0 (
  369.                         echo Массив не содержит элементов
  370.                         goto :eof
  371.                 )
  372.                
  373.                 for /l %%i in (0,1,!__maxindex!) do (
  374.                         call :set __value !__name!_%%i
  375.                         echo [%%i] !__value!
  376.                 )
  377.  
  378.                
  379.        
  380.         rem == set ==
  381.         rem Присвоение значения элементу
  382.         rem call :array set имя_массива индекс значение
  383.         ) else if /I "!__1!"=="set" (
  384.                
  385.                 if "!__4!"=="" (
  386.                         echo Не указано значение. Значение не может быть пустым
  387.                         goto :eof
  388.                 )
  389.                 rem Сохраняем параметры, для того, чтобы после вызова get они не потерялись    
  390.                 set _name=array_!__2!
  391.                 set /a _i=!__3!
  392.                 set _value=!__4!
  393.                        
  394.                 rem Получение значения обеспечивает нам проверку параметров
  395.                 rem Важно. После операции все локальные переменные (__*) очищаются
  396.                 call :array get !__2! !__3! _localresult
  397.                
  398.  
  399.                 rem Если результат get существует, то удаляем элемент
  400.                 rem Сообщения об ошибках в противном случае покажет сам get
  401.                 if defined _localresult (
  402.                         set !_name!_!_i!=!_value!
  403.                 )
  404.                
  405.                 set _localresult=
  406.                 set _name=
  407.                 set _i=
  408.                 set _value=
  409.                
  410.        
  411.         rem == delete ==
  412.         rem Удаление массива
  413.         rem call :array delete имя_массива
  414.         ) else if /I "!__1!"=="delete" (
  415.        
  416.                 rem Имя массива
  417.                 if "!__2!"=="" (
  418.                         echo Не указано имя массива
  419.                         goto :eof
  420.                 )
  421.                
  422.                
  423.                 rem Проверка существования массива
  424.                 call :array_notdefined !__2! __errors
  425.                
  426.                 rem Если есть ошибки, то выходим
  427.                 if not !__errors!==0 goto :eof
  428.                
  429.                 set __name=array_!__2!
  430.                
  431.                 rem Получаем размер
  432.                 call :set __count !__name!_count
  433.                 set /a __maxindex=__count-1
  434.                
  435.                 rem Удаляем все элементы
  436.                 for /l %%i in (0,1,!__maxindex!) do set !__name!_%%i=
  437.                 rem Удаляем размер
  438.                 set !__name!_count=
  439.                                
  440.         rem == del ==
  441.         rem Удаление элемента, элементов или всего массива
  442.         rem call :array del имя_массива [индекс_элемента|набор элементов=удаление всего массива]
  443.         rem Примеры:     call :array del myArr "4,6,8"  -  удаляет из массива myArr элементы с индексами 4, 6 и 8
  444.         rem                     call :array del myArr 9  -  удаляет из массива myArr 9й элемент
  445.         rem                             call :array del myArr   -       удаляет массив myArr
  446.         ) else if /I "!__1!"=="del" (
  447.        
  448.                 rem Если не указан индекс, то удаляем весь массив         
  449.                 if "!__3!"=="" (
  450.                         call :array delete !__2!
  451.                         goto :eof
  452.                 )
  453.                
  454.                 rem Если параметр не число, то перенаправляем на удаление по списку индексов
  455.                 set __localresult=
  456.                 call :is_number "!__3!" __localresult
  457.                 if !__localresult!==0 (
  458.                         call :array del_elements !__2! "!__3!"
  459.                         goto :eof
  460.                 )
  461.                
  462.                
  463.                 rem Если индекс указан, то удаляем только элемент
  464.                
  465.                 rem Сохраняем параметры, для того, чтобы после вызова get они не потерялись    
  466.                 set _name=array_!__2!
  467.                 set /a _i=!__3!
  468.                        
  469.                 rem Получение значения обеспечивает нам проверку параметров
  470.                 rem Важно. После операции все локальные переменные (__*) очищаются
  471.                 set _localresult=
  472.                 call :array get !__2! !__3! _localresult
  473.                 rem Если результат get не существует, то выходим
  474.                 rem Сообщения об ошибках в этом случае покажет сам get
  475.                 if not defined _localresult (
  476.                         set _name=
  477.                         goto :eof
  478.                 )
  479.                 set _localresult=
  480.  
  481.                
  482.                 rem Получаем размер
  483.                 call :set __count !_name!_count
  484.                 rem maxindex=count-2, так как идём до предпоследнего элемента
  485.                 set /a __maxindex=__count-2
  486.                 set /a __nextindex=!_i!
  487.  
  488.                 rem Пересчёт индексов
  489.                 for /l %%i in (!_i!,1,!__maxindex!) do (
  490.                         set /a __nextindex+=1
  491.                         call :set !_name!_%%i !_name!_!__nextindex!
  492.                 )
  493.                
  494.                 set /a !_name!_count-=1
  495.                
  496.                 rem Удаление последнего элемента (он был перемещёт на позицию вверх)
  497.                 set !_name!_!__nextindex!=
  498.                
  499.                 rem Удаляем локальные переменные
  500.                 set _name=
  501.                 set _i=
  502.        
  503.  
  504.         rem == del_elements ==
  505.         rem Удаление элементов по списку индексов
  506.         rem call :array del_elements имя_массива
  507.         rem Лучше использовать del
  508.         ) else if /I "!__1!"=="del_elements" (
  509.        
  510.                 rem Имя массива
  511.                 if "!__2!"=="" (
  512.                         echo Не указано имя массива
  513.                         goto :eof
  514.                 )
  515.                
  516.                
  517.                 rem Проверка существования массива
  518.                 call :array_notdefined !__2! __errors
  519.                
  520.                 rem Если есть ошибки, то выходим
  521.                 if not !__errors!==0 goto :eof
  522.  
  523.                 rem Проверка индексов
  524.                 if "!__3!"=="" (
  525.                         echo Не указан набор индексов
  526.                         goto :eof
  527.                 )
  528.                
  529.                 rem Имя массива с префиксом
  530.                 set __name=array_!__2!
  531.        
  532.        
  533.                 rem Приводим набор к цисловому набору вида ;54;2;3;5;
  534.                 call :to_intset "!__3!" __indexes
  535.  
  536.                 rem Получаем размер
  537.                 call :set __count !__name!_count
  538.                 set /a __maxindex=__count-1
  539.                
  540.                 rem Количество удаленных элементов
  541.                 rem Используется для поправки размера, и, главное, для смещения индексов
  542.                 set /a __deleted=0
  543.                
  544.                 rem Пересчёт индексов
  545.                 rem Идея состоит в том, что мы бежим по исходному массиву, и если попадаем в позицию
  546.                 rem которую нужно удалить, то в текущую позицию помещаем элемент, который будет идти
  547.                 set __exit_i_loop=0
  548.                 for /l %%i in (0,1,!__maxindex!) do (
  549.                         if not !__exit_i_loop!==1 (
  550.  
  551.                                 rem Индекс элемента в исходном массиве, соответствущий данному положению
  552.                                 set /a __newindex=%%i+!__deleted!
  553.                                 set __exit_j_loop=0
  554.                                
  555.                                 rem Пробегаемся по индексам вперёд, пока будут попадаться индексы элементов
  556.                                 rem которых требуется удалить.
  557.                                 for /l %%j in (!__newindex!,1,!__maxindex!) do (
  558.                                         if not !__exit_j_loop!==1 (
  559.                                        
  560.                                                 rem Если в наборе индексов к удалению содержится текущий, то
  561.                                                 rem он подлежит удалению, а значит индексы в результирующем массиве
  562.                                                 rem далее будут отставать от соответствующих в исходном на ещё одну позицию больше
  563.                                                 call :str_contains __indexes %%j __localresult
  564.                                                 if !__localresult!==1 (
  565.                                                         set /a __deleted+=1
  566.                                                 ) else (
  567.                                                         set __exit_j_loop=1
  568.                                                 )
  569.                                                
  570.                                         )
  571.                                        
  572.                                                                
  573.                                 )
  574.                                
  575.                                 rem Пересчитываем, чтобы понять, нужно ли дальше бежать, или нет
  576.                                 set /a __newindex=%%i+!__deleted!
  577.                                 if !__newindex! GTR !__maxindex! (
  578.                                         set __exit_i_loop=1
  579.                                 ) else (
  580.                                         call :set !__name!_%%i !__name!_!__newindex!
  581.                                 )
  582.                        
  583.                         )
  584.                 )
  585.                
  586.                 set /a !__name!_count=!__count!-!__deleted!
  587.                
  588.                 rem Удаление последнего элемента (он был перемещёт на позицию вверх)
  589.                 set !_name!_!__nextindex!=
  590.                
  591.         rem == add ==
  592.         rem Добавить элемент в конец массива или набор элементов
  593.         rem call :array add имя_массива значение
  594.         rem call :array add имя_массива набор !
  595.         rem Чтобы добавить набор, необходимо указать параметр !
  596.         rem Можно использовать вместо последней конструкции вызов процедуры expand
  597.         ) else if /I "!__1!"=="add" (
  598.                
  599.                 rem Имя массива
  600.                 if "!__2!"=="" (
  601.                         echo Не указано имя массива
  602.                         goto :eof
  603.                 )
  604.                
  605.                 rem Значение
  606.                 if "!__3!"=="" (
  607.                         echo Не задано значение. Значение не может быть пустым
  608.                         goto :eof
  609.                 )
  610.                
  611.                 rem Пареметр l указывает на то, что добавляется набор
  612.                 if /i "!__4!"=="!" (
  613.                         call :array expand !__2! "!__3!"
  614.                         goto :eof
  615.                 )
  616.                                                
  617.                 rem Проверка существования массива
  618.                 call :array_notdefined !__2! __errors
  619.                
  620.                 rem Если есть ошибки, то выходим
  621.                 if not !__errors!==0 goto :eof
  622.                
  623.                 rem Имя массива с префиксом
  624.                 set __name=array_!__2!
  625.                
  626.                 rem Получаем размер
  627.                 call :set __count !__name!_count
  628.                 rem Задаём значение
  629.                 set !__name!_!__count!=!__3!
  630.                 rem и увеличиваем размер
  631.                 set /a !__name!_count+=1
  632.                
  633.                
  634.         rem == expand ==
  635.         rem Добавить набор элементов в конец массива
  636.         rem call :array expand имя_массива набор элементов
  637.         rem Пример:               call :array expand myArr "'first line' 'Вторая строка' 12 54"
  638.         rem             добавление к массиву myArr 4х элементов
  639.         ) else if /I "!__1!"=="expand" (
  640.        
  641.                 rem Имя массива
  642.                 if "!__2!"=="" (
  643.                         echo Не указано имя массива
  644.                         goto :eof
  645.                 )
  646.                
  647.                 rem Набор
  648.                 if "!__3!"=="" (
  649.                         echo Не указан набор элементов. Набор не может быть пустым
  650.                         goto :eof
  651.                 )
  652.                
  653.                 rem Проверка существования массива
  654.                 call :array_notdefined !__2! __errors
  655.                
  656.                 rem Если есть ошибки, то выходим
  657.                 if not !__errors!==0 goto :eof
  658.                
  659.                 rem Имя массива с префиксом
  660.                 set __name=array_!__2!
  661.                
  662.                 rem Получаем размер
  663.                 call :set __count !__name!_count
  664.                
  665.                 rem Заменяем одинарные кавычки на двойные
  666.                 set __3=!__3:'="!
  667.                
  668.                 rem Создаем последовательно каждый элемент и присваиваем значение, начиная с последнего
  669.                 set /a __i=!__count!
  670.                 for %%i in (!__3!) do (
  671.                         rem ~ - убираем кавычки, которые необходимы для группировки
  672.                         set !__name!_!__i!=%%~i
  673.                         set /a __i+=1
  674.                 )
  675.                 set /a !__name!_count=!__i!
  676.                
  677.                
  678.         rem == copy ==
  679.         rem Копирование массива
  680.         rem call :array copy имя_копируемого имя_конечного
  681.         ) else if /I "!__1!"=="copy" (
  682.                
  683.                 rem Имя исходного массива
  684.                 if "!__2!"=="" (
  685.                         echo Не указано имя исходного массива
  686.                         goto :eof
  687.                 )
  688.                
  689.                 rem Имя целевого массива
  690.                 if "!__3!"=="" (
  691.                         echo Не указано имя целевого массива
  692.                         goto :eof
  693.                 )
  694.                
  695.                 rem Проверка существования массива
  696.                 call :array_notdefined !__2! __errors
  697.                
  698.                 rem Если есть ошибки, то выходим
  699.                 if not !__errors!==0 goto :eof
  700.                
  701.                
  702.                 rem Имена массивов с префиксом
  703.                 set _name=array_!__2!
  704.                 set _name_new=array_!__3!
  705.                
  706.                 rem Получаем размер
  707.                 call :set _count !_name!_count
  708.                 set /a _maxindex = !_count!-1
  709.                
  710.                 rem Удаляем целевой массив, если существует
  711.                 call :array_del_ifdef !__3!
  712.  
  713.                
  714.                 rem Копируем поэлементно
  715.                 for /l %%i in (0,1,!_maxindex!) do (
  716.                         call :set !_name_new!_%%i !_name!_%%i
  717.                 )
  718.                
  719.                 rem Копируем размер
  720.                 set /a !_name_new!_count=!_count!
  721.        
  722.                 rem Удаляем локальные переменные
  723.                 set _name=
  724.                 set _name_new=
  725.                 set _count=
  726.                 set _maxindex=
  727.                
  728.         rem == each ==
  729.         rem Вызов комманды для каждого элемента массива
  730.         rem В качество подстановок используйте:
  731.         rem     При вызове комманды:
  732.         rem             _i_ - индекс текущего элемента
  733.         rem             _val_ - значение текущего элемента
  734.         rem             call :array each имя_массива комманда x
  735.         rem
  736.         rem             Пример:
  737.         rem                     call :array new B "1 4 1 6 6 2"
  738.         rem                     set sum=0
  739.         rem                     call :array each B "set /a sum+=_val_" x
  740.         rem                     echo !sum!
  741.         rem             Выведет 20 - сумма всех элементов в массива
  742.         rem             При вызове процедуры:
  743.         rem                     %~1     - значение (~ - убираем кавычки)
  744.         rem                     %2      - номер индекса
  745.         rem
  746.         rem                     Пример:
  747.         rem                             call :array new B "1 4 1 6 6 2"
  748.         rem                             call :array each B to_string
  749.         rem                             echo !str!
  750.         rem                             :to_string
  751.         rem                                     set str=!str!%~1
  752.         rem                             goto :eof
  753.         rem             Выведет 141662
  754.        
  755.         ) else if /I "!__1!"=="each" (
  756.        
  757.                 rem Имя массива
  758.                 if "!__2!"=="" (
  759.                         echo Не указано имя исходного массива
  760.                         goto :eof
  761.                 )
  762.        
  763.                 rem Проверка существования массива
  764.                 call :array_notdefined !__2! __errors
  765.                
  766.                 rem Если есть ошибки, то выходим
  767.                 if not !__errors!==0 goto :eof
  768.                
  769.                
  770.                 rem Комманда
  771.                 if "!__3!"=="" (
  772.                         echo Не задана камманда each
  773.                         goto :eof
  774.                 )
  775.                
  776.                 set __is_command=0
  777.                 if /i "!__4!"=="x" (
  778.                         set __is_command=1
  779.                 )
  780.                
  781.                 set __command=!__3!
  782.                
  783.                 rem Имя массива с префиксом
  784.                 set __name=array_!__2!
  785.                
  786.                 rem Получаем размер
  787.                 call :set __count !__name!_count
  788.                 set /a __maxindex = !__count!-1
  789.                
  790.                 for /l %%i in (0,1,!__maxindex!) do (
  791.                         call :set _val_ !__name!_%%i
  792.                        
  793.                         if !__is_command!==1 (
  794.                                 call :str_replace __command _i_ %%i __exec
  795.                                 call :str_replace __exec _val_ "!_val_!"
  796.                                 !__exec!
  797.                         ) else (
  798.                                 call :!__command! "!_val_!" %%i
  799.                         )
  800.                        
  801.                 )
  802.                
  803.                
  804.         rem == sort ==
  805.         rem Сортировка массива
  806.         rem Укажите параметр R для сортировки в обратном порядке
  807.         rem call :array sort имя_массива
  808.         rem call :array sort имя_массива R   - сортировка в обратном порядке
  809.         ) else if /I "!__1!"=="sort" (
  810.        
  811.                 rem Имя массива
  812.                 if "!__2!"=="" (
  813.                         echo Не указано имя исходного массива
  814.                         goto :eof
  815.                 )
  816.        
  817.                 rem Проверка существования массива
  818.                 call :array_notdefined !__2! __errors
  819.                
  820.                 rem Если есть ошибки, то выходим
  821.                 if not !__errors!==0 goto :eof
  822.                
  823.                
  824.                 rem Реверсивная сортировка
  825.                 if /I "!__3!"=="R" (
  826.                         set _rev=/r
  827.                 )
  828.                
  829.                
  830.                 set _shortname=!__2!
  831.                 rem Имя массива с префиксом
  832.                 set _name=array_!__2!
  833.                
  834.                 rem Генерируем имя для временного файла
  835.                 set _tmpfile=%TMP%\array_sort_%random%%random%
  836.  
  837.                 rem Сохраняем массив в файл
  838.                 call :array list !_shortname! > "!_tmpfile!.txt"
  839.                
  840.                 rem Сортируем из файла
  841.                 sort !_rev! !_tmpfile!.txt /o "!_tmpfile!_sorted.txt"
  842.                
  843.                 rem Удаляем текущиий массив - можно не удалять, потому что размер останется таким же
  844.                 rem и все переменные просто перезапишутся
  845.                 rem call :array delete !_shortname!
  846.                
  847.                 rem Читаем результат из файла
  848.                 call :array load_unsafe !_shortname! "!_tmpfile!_sorted.txt"
  849.                
  850.                 rem Удаляем временные файлы
  851.                 del /f /q "!_tmpfile!_sorted.txt" "!_tmpfile!.txt"
  852.                
  853.                
  854.                 rem Удаляем локальные переменные
  855.                 set _name=
  856.                 set _tmpfile=
  857.                 set _shortname=
  858.                 set _rev=
  859.                
  860.                
  861.         rem == find ==
  862.         rem Поиск элемента
  863.         rem Возвращает номер первого найденного элемента или -1, если не найдено
  864.         rem Используёте параметр I для игнорирования регистра
  865.         rem call :array find имя_массива искомый_элемент N [имя_целевой_переменной=_l] - N - лобой символ, отличный от i
  866.         rem call :array find имя_массива искомый_элемент I [имя_целевой_переменной=_l]  - поиск с игнорированием регистра
  867.         rem Пример: call :array find myArr "Себастьян Перейро" N sebastNum
  868.         rem возвращает в переменную sebastNum номер элемента в массиве myArr, содержащий строку Себастьян Перейро с учётом регистра
  869.         rem N - любой символ, кроме I, чтобы не включить игнорирование регистра
  870.         ) else if /i "!__1!"=="find" (
  871.        
  872.                 rem Имя массива
  873.                 if "!__2!"=="" (
  874.                         echo Не указано имя исходного массива
  875.                         goto :eof
  876.                 )
  877.        
  878.                 rem Проверка существования массива
  879.                 call :array_notdefined !__2! __errors
  880.                
  881.                 rem Если есть ошибки, то выходим
  882.                 if not !__errors!==0 goto :eof
  883.                
  884.                 rem Значение
  885.                 if "!__3!"=="" (
  886.                         echo Не задано значение. Значение не может быть пустым
  887.                         goto :eof
  888.                 )
  889.                 set __find=!__3!
  890.                
  891.                 rem Имя массива с префиксом
  892.                 set __name=array_!__2!
  893.                
  894.                 rem Игнорирование регистра
  895.                 if /i "!__4!"=="I" (
  896.                         set __ignorecase=1
  897.                 )
  898.                
  899.                 rem Имя целевой переменной
  900.                 set __var=_l
  901.                 if not "!__5!"=="" (
  902.                         set __var=!__5!
  903.                 )
  904.                
  905.                 rem Получаем размер
  906.                 call :set __count !__name!_count
  907.                 set /a __maxindex=__count-1
  908.                
  909.                 rem Устанавливаем результат -1
  910.                 set !__var!=-1
  911.                
  912.                 set __exit_loop=0
  913.                 for /l %%i in (0,1,!__maxindex!) do (
  914.                         if not !__exit_loop!==1 (
  915.                                 rem Читаем значение элемента
  916.                                 call :set __value !__name!_%%i
  917.                                 rem Сравниваем со строкой поиска с ignorecase
  918.                                 rem Постановка флага как переменной вызывает ошибку
  919.                                 if !__ignorecase!==1 if /i "!__value!"=="!__find!" (
  920.                                                 set __exit_loop=1
  921.                                                 set !__var!=%%i
  922.                                 )
  923.                                
  924.                                 if not !__ignorecase!==1 if "!__value!"=="!__find!" (
  925.                                                 set __exit_loop=1
  926.                                                 set !__var!=%%i
  927.                                 )
  928.                         )
  929.                 )
  930.                
  931.                
  932.         )
  933.         call :clear_local
  934.  
  935. goto :eof
  936.  
  937.  
  938.  
  939. rem Копирует значение одной переменной в другую
  940. rem Плюс в том, что имя переменной, значение которой извлекается, может быть составным
  941. rem call :set имя_целевой_переменной имя_переменной_содержищее_значение
  942. :set
  943.         set %~1=!%~2!
  944. goto :eof
  945.  
  946. rem Удаление локальных переменных (начинаются с __)
  947. :clear_local
  948.         rem Устанавливаю переменную __, чтобы set __ не возвращал "Переменная среды __ не определена"
  949.         set __=0
  950.         for /F "usebackq delims==" %%i in (`set __`) do set %%i=
  951. goto :eof
  952.  
  953.  
  954. :array_del_ifdef
  955.         call :array_notdefined %1 __array_del_ifdef_result H
  956.         if !__array_del_ifdef_result!==0 call :array delete %1
  957. goto :eof
  958.  
  959. rem Проверка существования массива
  960. :array_notdefined
  961.         rem Устанавливаем имя целевой переменной
  962.         set __var=_l
  963.        
  964.         rem Тихая проверка - не выводить сообщение
  965.         set __hide=0
  966.        
  967.         if not "%2"=="" (
  968.                 set __var=%2
  969.         )
  970.        
  971.         if /i "%3"=="h" (
  972.                 set __hide=1
  973.         )
  974.        
  975.         if not defined !__var! set /a !__var!=0
  976.        
  977.         rem Проверка существования переменной, содержащей размер
  978.         if not defined array_%~1_count (
  979.                 if not !__hide!==1 echo Массив %~1 не определен
  980.                 set /a !__var!+=1
  981.         )
  982.        
  983. goto :eof
  984.  
  985. rem Перевод набора индексов к виду ;1;62;2;5;6;
  986. rem чтобы можно было выполнять проверку наличия числа: ;%i%;
  987. rem call :to_intset набор [имя_целевой_переменной=_l]
  988. rem Пример:
  989. rem call :to_intset "1 4 76 , 56, 34 ,6" set
  990. rem echo %set%
  991. rem выведет: ;1;4;76;56;34;6;
  992. :to_intset
  993.         rem Устанавливаем имя целевой переменной
  994.         set __var=_l
  995.        
  996.         if not "%2"=="" (
  997.                 set __var=%2
  998.         )
  999.        
  1000.         rem Добавляем елементы набора к строке
  1001.         set __intset=
  1002.         for %%i in (%~1) do (
  1003.                         set __intset=!__intset!;%%i
  1004.         )
  1005.        
  1006.         rem Закрывающая ;
  1007.         set __intset=!__intset!;
  1008.        
  1009.         rem Записываем результат
  1010.         call :set !__var! __intset
  1011.        
  1012.         set __intset=
  1013.        
  1014. goto :eof
  1015.  
  1016.  
  1017. rem Является ли значение(!) числом
  1018. rem call :is_number значение [имя_целевой_переменной=_l]
  1019. :is_number
  1020.         rem Устанавливаем имя целевой переменной
  1021.         set _var=_l
  1022.        
  1023.         if not "%2"=="" (
  1024.                 set _var=%2
  1025.         )
  1026.        
  1027.         set _val=%~1
  1028.         set _newval=%~1
  1029.         rem Выход из цикла, а заодно и индикатор, потому что
  1030.         rem Если из цикла был совершён вынужденный выход, то значит число
  1031.         set _exit_loop_local=0
  1032.  
  1033.         rem Трюк в том, чтобы вырезать все цифры, и если останется пустая строка, то значит было число
  1034.         rem Подобную реализацию видел на каком-то сайте, посвящённом быдлокодерам, но вот здесь пригодилось
  1035.         for /l %%i in (0,1,9) do (
  1036.                 if not !_exit_loop_local!==1 (
  1037.                         rem Новое имя с новой подстановкой текущей цифры
  1038.                         set _newname="_newval:%%i="
  1039.                         call :set _newval !_newname!
  1040.                        
  1041.                         if "!_newval!"=="" (
  1042.                                 set _exit_loop_local=1
  1043.                         )
  1044.                 )
  1045.         )
  1046.        
  1047.         rem Записываем результат
  1048.         set !_var!=!_exit_loop_local!
  1049.        
  1050.         set _var=
  1051.         set _exit_loop_local=
  1052.         set _val=
  1053.         set _newval=
  1054.         set _newname=
  1055.         set _name=
  1056.                
  1057. goto :eof
  1058. rem Есть путь быстрее, но в случае передачи строки выводится сообщение об ошибке,
  1059. rem которое никак не перехватить, однако определение всё же происходит
  1060. rem set __tmp=
  1061. rem set /a __tmp=%1
  1062. rem if not defined __tmp (
  1063. rem     echo string
  1064. rem ) else (
  1065. rem             echo number
  1066. rem )
  1067.  
  1068.  
  1069.  
  1070. rem Замена подстроки
  1071. rem call :str_replace имя_исходной_переменной искомая_строка подстановка [имя_целевой_переменной=имя_исходной_переменной]
  1072. rem set str=Привет, Маша. Как дела?
  1073. rem call :str_replace str "как дела" "Как настроение" str2
  1074. rem echo !str2!
  1075. rem Результат: Привет, Маша. Как настроение?
  1076. :str_replace
  1077.         rem Устанавливаем имена целевой и исходной переменных
  1078.         set _var=%1
  1079.         set _result=%1
  1080.        
  1081.         rem Искомая строка
  1082.         set _from=%~2
  1083.         rem Строка подстановка
  1084.         set _to=%~3
  1085.        
  1086.         if not "%4"=="" (
  1087.                 set _result=%4
  1088.         )
  1089.        
  1090.         set _newvarname=!_var!:!_from!=!_to!
  1091.         call :set !_result! "!_newvarname!"
  1092.        
  1093.         set _var=
  1094.         set _result=
  1095.         set _from=
  1096.         set _to=
  1097.         set _newvarname=
  1098. goto :eof
  1099.  
  1100. rem Проверка наличия цисла в наборе
  1101. rem Набор должен иметь вид ;3;645;12;56;7;0;
  1102. rem В целевой переменной будет 1 в случае успеха, и 0 в противном случае
  1103. rem call :str_contains имя_переменной_с_набором число [целевая_переменная=_el]
  1104. :str_contains
  1105.         rem Устанавливаем имя целевой переменной
  1106.         set _var=_l
  1107.        
  1108.         if not "%3"=="" (
  1109.                 set _var=%3
  1110.         )
  1111.        
  1112.        
  1113.         rem Новое имя переменной с подстановкой. имя_переменной:;число;=#
  1114.         rem таким образом заменяем число, окруженное ; на решётку
  1115.         set _newstr=%1:;%2;=#
  1116.        
  1117.         call :set _newstr "!_newstr!"
  1118.  
  1119.         rem Если число присутствует, то новое значение не совпадёт состарым,
  1120.         rem т.к. в новом искомое число будет заменено на решётку
  1121.         if not "!_newstr!"=="!%1!" (
  1122.                 set !_var!=1
  1123.         ) else (
  1124.                 set !_var!=0
  1125.         )
  1126.        
  1127.         set _var=
  1128.         set _newstr=
  1129. goto :eof
  1130.  
  1131. :exit
  1132. ENDLOCAL
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top