Информация
Услуги
  • Внедрение
  • Настройка
  • Поддержка
  • Ремонт
Контакты
Новинка
Распродажа
Новости
Доставка
Оплата
Загрузки
  • Прошивки
    • WinBox
    • RouterOS
    • Мобильные приложения MikroTik
    • Архив
  • RouterOS
  • Мобильные приложения MikroTik
  • Архив
Форум
Настройка
    info@mikrotik.moscow
    +7 495 320-55-52
    Заказать звонок
    Mikrotik.moscow
    Каталог
    • Акции
      Акции
    • Маршрутизаторы
      Маршрутизаторы
    • Коммутаторы
      Коммутаторы
    • Радиомосты и уличные точки доступа
      Радиомосты и уличные точки доступа
    • Wi-Fi для дома и офиса
      Wi-Fi для дома и офиса
    • LTE/5G
      LTE/5G
    • Powerline адаптеры
      Powerline адаптеры
    • IoT устройства
      IoT устройства
    • Оборудование 60 ГГц
      Оборудование 60 ГГц
    • Материнские платы RouterBOARD
      Материнские платы RouterBOARD
    • Корпуса
      Корпуса
    • Интерфейсы
      Интерфейсы
    • SFP/QSFP трансиверы
      SFP/QSFP трансиверы
    • Аксессуары
      Аксессуары
    • Антенны
      Антенны
    • Архив
      Архив
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Скачать WinBox Скачать Прошивки Форум > RouterOS Форум > SwOS Форум > Железо
    Mikrotik.moscow
    Каталог
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Mikrotik.moscow
    Телефоны
    +7 495 320-55-52
    Заказать звонок
    0
    0
    0
    Mikrotik.moscow
    • +7 495 320-55-52
      • Назад
      • Телефоны
      • +7 495 320-55-52
      • Заказать звонок
    • info@mikrotik.moscow
    • г. Москва, ул. Бакунинская, 84
    • Пн-Пт: 09-00 до 18-00
      Сб-Вс: выходной


    • Кабинет
    • 0 Сравнение
    • 0 Избранное
    • 0 Корзина
    Главная
    Форум
    Форум
    RouterOS
    Функция добавления элемента в массив

    Функция добавления элемента в массив

    Форумы: RouterOS, Аппаратное обеспечение, SwOS, Обратная связь, Объявления, Сторонние инструменты
    Поиск  Пользователи  Правила  Войти
    Страницы: 1
    RSS
    Функция добавления элемента в массив, RouterOS
     
    royalpublishing
    Guest
    #1
    0
    12.06.2014 21:53:00
    Я создал простую функцию для добавления элементов в массив, но столкнулся с некоторыми проблемами. Функция работает нормально, если имя массива, которое передаешь как первый аргумент, уже существует, переменная действительно является массивом, а значение не равно null. Я хотел бы вызывать эту функцию так, чтобы, если массива ещё нет, она создавала его и добавляла второй параметр. Проблема в том, что если массива нет, его значение равно nil, и получается, что первый аргумент как будто не передавали, из-за чего выходят странные результаты.

    Вот сама функция.

    Usage: [$arrayPush]
    Вводишь имя массива и значение, которое нужно добавить в конец массива:

    :global arrayPush do={
     :if ($1=“”) do={ :error “Вы не указали имя массива.”; }
     :if ($2=“”) do={ :error “Вы не указали значение для добавления.”; }
     :local string;
     :if ([:typeof $1]=“array”) do={
       :foreach item in=$1 do={
         :set string ($string . “,” . $item);
       }
       :set string ($string . “,” . $2);
       :set string [:toarray $string];
       :return $string;
     } else={
       :error “Первый аргумент не является массивом.”;
     }
    }

    Вот пример, что я имею в виду:

    :global myVar;  
    :set myVar [:toarray $myVar];
    :set myVar [$arrayPush $myVar “some value”];

    Поскольку $myVar равен nil, функция toarray по сути ничего не делает, и следующая строка даёт неожиданные результаты. Точно объяснить сложно, но надеюсь, суть понятна. Есть идеи, как это обойти? Сейчас я могу только проверить, существует ли массив перед вызовом функции, и если нет — создать переменную как строку, а потом конвертировать в массив, но это слишком много лишних шагов.
     
     
     
    palii
    Guest
    #2
    0
    29.04.2019 13:22:00
    Отлично! Спасибо за это. Я не знал, что можно так добавлять элементы в массивы (даже объединять другие массивы!).
     
     
     
    Retral
    Guest
    #3
    0
    27.08.2019 02:34:00
    Это прекрасно
     
     
     
    royalpublishing
    Guest
    #4
    0
    30.06.2014 16:02:00
    Вот окончательная версия функции, я добавил возможность вставлять значение в определённую позицию ключа внутри массива. Использование: [$arrayPush <$название массива> <позиция ключа для вставки значения (0-n или -1)>]. Введите имя массива, значение и позицию ключа, куда нужно поместить значение. Чтобы добавить значение в конец массива, укажите -1. Если массив ещё не существует, необходимо объявить переменную и присвоить ей "" перед вызовом функции.

    :global arrayPush do={
     :if ($2="") do={
       :error "Вы не указали значение для добавления в массив."
     }
     :if ($1!="" && $3="") do={
       :error "Вы не указали позицию ключа для вставки значения в массив."
     }
     :if (($3<(-1)) || (([:typeof $3]!="num") && ([:typeof $3]!="str")) || ($3>([:len $1]-1))) do={
       :error "Неверный аргумент 2."
     }
     :local string;
     :if ([:typeof $1]="array" && $3=(-1)) do={
       :foreach item in=$1 do={
         :set string ($string . "," . $item);
       }
       :set string ($string . "," . $2);
       :set string [:toarray $string];
       :return $string;
     }
     :if ([:typeof $1]="array" && [:len $1]>="0") do={
       :local counter "0";
       :foreach item in=$1 do={
         :if ($counter!=[:tonum $3]) do={
           :set string ($string . "," . $item);
           :set counter ($counter+1);
         } else={
           :set string ($string . "," . $2);
           :set string ($string . "," . $item);
           :set counter ($counter+1);
         }
       }
       :set string [:toarray $string];
       :return $string;
     }
     :if ($1="") do={
       :set string $2;
       :set string [:toarray $string];
       :return $string;
     }
    }
     
     
     
    rextended
    Guest
    #5
    0
    30.06.2014 17:59:00
    Спасибо, что поделились! Надеюсь, вам понравится эта короткая функция, которую я сделал для вас:  
    # Использование: [$arrayXpush <$имя массива> <значение> <позиция ключа для вставки значения>]
    # <$имя массива> — имя массива, если его нет или не передан массив, функция работает так, будто передан пустой массив  
    # <значение> может быть любым типом, если пустое — просто возвращается $array, если массива нет — возвращается пустой массив  
    # <позиция ключа для вставки значения> — позиция ключа, куда вставить значение  
    # если число < 0 — вставка в начало  
    # если число больше длины массива — вставка в конец  
    # если третий параметр — пустая строка или опущен, по умолчанию значение ставится в конец массива  
    # если третий параметр не число, по умолчанию значение ставится в начало массива  

    :global arrayXpush do={

    :local arrX value=[:toarray $1];
    :if ([:len $arrX] = 0) do={ :set $arrX value=[:toarray ""]; };
    :local arrXlen value=[:len $arrX];

    :local valX value=[:tostr $2];
    :if ($valX = "") do={ :return value=$arrX; };  

    :local posX value=([:tostr $3]);
    :if ($posX = "") do={ :set $posX value=($arrXlen + 1); };  
    :set $posX value=([:tonum $posX] + 0);
    :if ($posX < 0) do={ :set $posX value=0; };  
    :if ($posX > $arrXlen) do={ :set $posX value=$arrXlen; };  

    :if ($posX = 0) do={ :return value=($valX,$arrX); };  

    :if ($posX = $arrXlen) do={ :return value=($arrX,$valX); };  

    :return value=([:pick $arrX 0 ($posX - 1)],$valX,[:pick $arrX ($posX - 1) $arrXlen]);

    };  

    Теперь вы можете попробовать добавить следующее: если 4-й параметр равен "R" и значение <позиции ключа для вставки> находится в пределах массива, функция заменит значение, а не вставит его.
     
     
     
    palii
    Guest
    #6
    0
    27.04.2019 23:04:00
    Отличная работа, ребята. Похоже, теперь добавлять значения в массивы стало гораздо проще. Например: :local myarray {1;2;3;4}  
    :set ($myarray->[:len $myarray]) 5
    :log info $myarray Выведет: 1;2;3;4;5 Просто делюсь на случай, если кто-то найдёт эту тему.
     
     
     
    eworm
    Guest
    #7
    0
    29.04.2019 13:14:00
    Всё это выглядит слишком замысловато. Правильный способ таков: :set $MyArray ($MyArray, $Value);
     
     
     
    Jotne
    Guest
    #8
    0
    27.08.2019 07:02:00
    Этот способ больше похож на объединение двух переменных, чем на работу с массивом. Лучший способ работать с массивами выглядит так:  
    {  
    :local myarray {type="ford";model="mustang";color="green"}  
    :set ( "$myarray"->"year" ) "2015"  
    :set ( "$myarray"->"color" ) "blue"  
    :put $myarray  
    :put ( "$myarray"->"model" )  
    }  
    color=blue;model=mustang;type=ford;year=2015  
    mustang  

    Здесь мы делаем следующее: создаём массив, добавляем элемент year и устанавливаем его в 2015, меняем элемент color на blue, выводим массив, выводим модель из массива.  

    Таким образом можно работать с массивом, не зная расположения данных, обращаясь к ним по имени.  

    Если сделать так, то будет ошибка и появятся дублирующиеся поля:  
    :set $myarray ($myarray, "color=white")  

    Пример:  
    {  
    :local myarray {type="ford";model="mustang";color="green";year=2012}  
    :set $myarray ($myarray, "color=white")  
    :put $myarray  
    }  
    color=white;color=green;model=mustang;type=ford;year=2012  

    Так машина белая или зелёная?
     
     
     
    pe1chl
    Guest
    #9
    0
    27.08.2019 09:39:00
    Меня в таких решениях обычно беспокоит вопрос: что же там происходит «под капотом»… Может, это моя ошибка, ведь я начал программировать 40 лет назад, и тогда красивые решения часто оказывались слишком медленными для практического применения. Конечно, сегодня ситуация немного изменилась, хотя многие тормоза современных систем всё ещё можно объяснить небрежным кодом от людей, которые не знают, что такое эффективность. Вот, например, выражение :set $MyArray ($MyArray, $Value); выглядит красиво и просто, но я боюсь, что при добавлении каждого нового значения оно копирует весь существующий массив целиком. А это может обернуться катастрофой, если в массиве много элементов.
     
     
     
    Retral
    Guest
    #10
    0
    30.09.2020 17:59:00
    Спасибо за ваше сообщение. Обязательно учту это в следующий раз, когда буду программировать.
     
     
     
    SiB
    Guest
    #11
    0
    30.09.2020 23:07:00
    Такая тема получилась, что я решил добавить свой ответ про функции из прошлого, надеюсь, это немного прояснит пост :). #4 вместе с #7 — они содержат дополнительную информацию и викторину.
     
     
     
    Страницы: 1
    Читают тему
    +7 495 320-55-52
    info@mikrotik.moscow
    Электрозаводская, Бауманская
    Москва, ул. Бакунинская, 84с21
    Конфиденциальность Оферта
    © 2026 «Mikrotik.Moscow»
    Главная Каталог 0 Корзина 0 Избранные Кабинет 0 Сравнение Акции Контакты Услуги Бренды Отзывы Компания Лицензии Документы Реквизиты Поиск Блог Обзоры