Как выбрать из массива элементы удовлетворяющие условиям


Numpy массив, как выбрать индексы, удовлетворяющие нескольким условиям?

Предположим, у меня есть массив numpy x = [5, 2, 3, 1, 4, 5] , y = ['f', 'o', 'o', 'b', 'a', 'r'] . Я хочу выбрать элементы в y , соответствующие элементам в x , которые больше 1 и меньше 5.

Я пытался

x = array([5, 2, 3, 1, 4, 5]) y = array(['f','o','o','b','a','r']) output = y[x > 1 & x < 5] # desired output is ['o','o','a'] 

но это не работает. Как бы я это сделал?

python numpy Поделиться Источник Bob     12 июня 2010 в 23:28

6 Ответов



176

Ваше выражение работает, если вы добавляете круглые скобки:

>>> y[(1 < x) & (x < 5)] array(['o', 'o', 'a'], dtype='|S1') 

Поделиться jfs     13 июня 2010 в 00:50



30

IMO OP на самом деле не хочет np.bitwise_and() (aka &) , но на самом деле хочет np.logical_and() , потому что они сравнивают логические значения, такие как True и False - см. Этот пост SO на логическом против побитового , чтобы увидеть разницу.

>>> x = array([5, 2, 3, 1, 4, 5]) >>> y = array(['f','o','o','b','a','r']) >>> output = y[np.logical_and(x > 1, x < 5)] # desired output is ['o','o','a'] >>> output array(['o', 'o', 'a'], dtype='|S1') 

И эквивалентный способ сделать это-с помощью np.all() , установив аргумент axis соответствующим образом.

>>> output = y[np.all([x > 1, x < 5], axis=0)] # desired output is ['o','o','a'] >>> output array(['o', 'o', 'a'], dtype='|S1') 

по количеству:

>>> %timeit (a < b) & (b < c) The slowest run took 32.97 times longer than the fastest. This could mean that an intermediate result is being cached. 100000 loops, best of 3: 1.15 µs per loop >>> %timeit np.logical_and(a < b, b < c) The slowest run took 32.59 times longer than the fastest. This could mean that an intermediate result is being cached. 1000000 loops, best of 3: 1.17 µs per loop >>> %timeit np.all([a < b, b < c], 0) The slowest run took 67.47 times longer than the fastest. This could mean that an intermediate result is being cached. 100000 loops, best of 3: 5.06 µs per loop 

таким образом, использование np.all() медленнее, но & и logical_and примерно одинаковы.

Поделиться Mark Mikofski     05 сентября 2013 в 19:23



19

Добавьте одну деталь к ответам @J.F. Себастьяна и @Mark Микофски:
Если вы хотите получить соответствующие индексы (а не фактические значения массива), то вам подойдет следующий код:

Для удовлетворения нескольких (всех) условий:

select_indices = np.where( np.logical_and( x > 1, x < 5) )[0] # 1 < x <5 

Для удовлетворения нескольких (или) условий:

select_indices = np.where( np.logical_or( x < 1, x > 5 ) )[0] # x <1 or x >5 


Поделиться Good Will     18 ноября 2014 в 16:03



5

Мне нравится использовать np.vectorize для таких задач. Рассмотреть следующее:

>>> # Arrays >>> x = np.array([5, 2, 3, 1, 4, 5]) >>> y = np.array(['f','o','o','b','a','r']) >>> # Function containing the constraints >>> func = np.vectorize(lambda t: t>1 and t<5) >>> # Call function on x >>> y[func(x)] >>> array(['o', 'o', 'a'], dtype='<U1') 

Преимущество заключается в том, что вы можете добавить еще много типов ограничений в векторизованную функцию.

Надеюсь, это поможет.

Поделиться ''     09 ноября 2017 в 06:45



1

На самом деле я бы сделал это именно так:

L1-это индексный список элементов, удовлетворяющих условию 1; (Возможно, вы можете использовать somelist.index(condition1) или np.where(condition1) для получения L1.)

Аналогично, вы получаете L2, список элементов, удовлетворяющих условию 2;

Затем вы находите пересечение, используя intersect(L1,L2) .

Вы также можете найти пересечение нескольких списков, если вы получаете несколько условий для удовлетворения.

Затем можно применить индекс в любом другом массиве, например, X.

Поделиться Shuo Yang     29 июня 2017 в 23:49



0

Для массивов 2D вы можете сделать это. Создайте маску 2D, используя условие. Введите маску условия в int или float, в зависимости от массива, и умножьте ее на исходный массив.

In [8]: arr Out[8]: array([[ 1., 2., 3., 4., 5.], [ 6., 7., 8., 9., 10.]]) In [9]: arr*(arr % 2 == 0).astype(np.int) Out[9]: array([[ 0., 2., 0., 4., 0.], [ 6., 0., 8., 0., 10.]]) 

Поделиться Gautam     08 февраля 2019 в 21:56


Похожие вопросы:


Использование нескольких уровней маски логического индекса в NumPy

У меня есть следующий код, который сначала выбирает элементы массива NumPy с маской логического индекса: import numpy as np grid = np.random.rand(4,4) mask = grid > 0.5 Я хочу использовать вторую...


Numpy 2d массив, выберите индексы, удовлетворяющие условиям из 2 массивов

У меня есть два массива 3x3. Один из них указывает, является ли элемент черным (скажем, 0-белый, 1-черный), а другой-какова стоимость элемента. Есть ли хороший способ получить индексы, например,...


Найдите элементы массива numpy, удовлетворяющие условию

У меня есть массив numpy, и я хочу найти элементы, удовлетворяющие моему условию Коды, как показано ниже: import numpy as np a = np.array([[1, 2], [1, 3], [1, 2]]) b = np.array([1, 2]) c = (a == b)...


numpy binning: как получить индексы массива, удовлетворяющие предикату

У меня есть вектор g значений длины 1024 и меньший вектор f размера 32, определяющий границы Бина. v и f сортируются в порядке возрастания. Я хочу вернуть массив векторов, т. е. [v_1,v_2,v_3,...]...


Условная индексация с Numpy ndarray

У меня есть матрица Numpy ndarray с плавающими значениями, и мне нужно выбрать специальные строки, где некоторые столбцы имеют значения, удовлетворяющие определенным критериям. Например,...


Индексы элементов в массиве NumPy, удовлетворяющие условиям на значение и индекс

У меня есть массив NumPy, A . Я хочу знать индексы элементов в A равны значению и какие индексы удовлетворяют некоторому условию: import numpy as np A = np.array([1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3,...


Возвращает элементы из массива 2D numpy, удовлетворяющие определенным условиям

У меня есть (огромный) массив 2D. Например: a=[[1,2],[2,3],[4,5]] Мне нужно извлечь из него элементы, удовлетворяющие определенным условиям a[:,0]>1 and a[:,1]>2 таким образом, я получаю...


Возвращает индексы массивов в массиве 2D numpy, удовлетворяющие условию

У меня есть большой массив 2D numpy и я хочу найти индексы 1D массивов внутри него, которые удовлетворяют условию: например, имеют по крайней мере значение, большее заданного порога x. Я уже могу...


Как индексировать массив numpy, используя другой массив numpy, содержащий индексы?

Это должно быть простой задачей, но мне стыдно признаться, что я застрял. У меня есть массив numpy, называемый X : X.shape - это (10,3) и выглядит так [[ 0. 0. 13. ] [ 0. 0. 1. ] [ 0. 4. 16. ] ...,...


найдите общие индексы, удовлетворяющие 2 условиям в matlab

У меня есть массив 2D и довольно большой (8000x6000). Есть два условия, которые выполняются для одного и того же массива (cond1 и cond2) , и я хочу их согласовать, найти общие индексы,...


coderoad.ru

Формулы массива в Excel

Терминология

Под массивом обычно понимают набор данных, объединенных в группу. Массивы бывают одномерные (элементы массива образуют строку или столбец) или двумерные (матрица). Легко сообразить, что почти в любой таблице Excel при желании можно найти один или несколько таких массивов:

Формулы массива в Excel - это специальные формулы для обработки данных из таких массивов. Формулы массива делятся на две категории - те, что возвращают одно значение и те, что дают на выходе целый набор (массив) значений. Рассмотрим их на простых примерах...

Пример 1. Классика жанра - товарный чек

Задача: рассчитать общую сумму заказа. Если идти классическим путем, то нужно будет добавить столбец, где перемножить цену и количество, а потом взять сумму по этому столбцу. Если же применить формулу массива, то все будет гораздо красивее:

  1. выделяем ячейку С7
  2. вводим с клавиатуры =СУММ(
  3. выделяем диапазон B2:B5
  4. вводим знак умножения (звездочка)
  5. выделяем диапазон C2:C5 и закрываем скобку функции СУММ - в итоге должно получиться так:

  6. чтобы Excel воспринял нашу формулу как формулу массива жмем не Enter, как обычно, а Ctrl + Shift + Enter

Вуаля!

Т.е. Excel произвел попарное умножение элементов массивов B2:B5 и C2:C5 и образовал новый массив стоимостей (в памяти компьютера), а затем сложил все элементы этого нового массива.

Обратите внимание на фигурные скобки, появившиеся в формуле - отличительный признак формулы массива. Вводить их вручную с клавиатуры бесполезно - они автоматически появляются при нажатии Ctrl + Shift + Enter.

Пример 2. Разрешите Вас... транспонировать?

При работе с таблицами часто возникает необходимость поменять местами строки и столбцы, т.е. развернуть таблицу на бок, чтобы данные, которые раньше шли по строке, теперь располагались в столбцах и наоборот. В математике такая операция называется транспонированием. При помощи формулы массива и функции ТРАНСП (TRANSPOSE) это делается на раз.

Допустим, имеем двумерный массив ячеек, который хотим транспонировать.

  • Выделяем диапазон ячеек для размещения транспонированной таблицы. Поскольку исходный массив ячеек был 8 строк на 2 столбца, то надо выделить диапазон пустых ячеек размером 2 строки на 8 столбцов.
  • вводим функцию транспонирования =ТРАНСП(   
  • в качестве аргумента функции выделяем наш массив ячеек A1:B8

жмем Ctrl + Shift + Enter и получаем "перевернутый массив" в качестве результата:

Редактирование формулы массива

Если формула массива расположена не в одной ячейке (как в Примере 1), а в нескольких ячейках (как в Примере 2), то Excel не позволит редактировать или удалить одну отдельно взятую формулу (например в ячейке D10) и выдаст предупреждающее сообщение Невозможно изменить часть массива.

Для редактирования формулы массива необходимо выделить весь диапазон (A10:h21 в нашем случае) и изменить формулу в строке формул (или нажав F2). Затем необходимо повторить ввод измененной формулы массива, нажав сочетание клавиш Ctrl + Shift + Enter.

Excel также не позволит свободно перемещать ячейки, входящие в формулу массива или добавлять новые строки-столбцы-ячейки в диапазон формулы массива (т.е. в диапазон A10:h21 в нашем случае)

Пример 3. Таблица умножения

Вспомните детство, школу, свою тетрадку по математике... На обороте тетради на обложке было что? Таблица умножения вот такого вида:

При помощи формул массива она вся делается в одно движение:

  1. выделяем диапазон B2:K11
  2. вводим формулу =A2:A11*B1:K1
  3. жмем Ctrl + Shift + Enter, чтобы Excel воспринял ее как формулу массива

и получаем результат:

Пример 4. Выборочное суммирование

Посмотрите как при помощи одной формулы массива красиво и легко выбираются данные по определенному товару и заказчику:

 В данном случае формула массива синхронно пробегает по всем элементам диапазонов C3:C21 и B3:B21, проверяя, совпадают ли они с заданными значениями из ячеек G4 и G5. Если совпадения нет, то результат равенства ноль, если совпадение есть, то единица. Таким образом суммы всех сделок, где заказчик не ANTON и товар не Boston Crab Meat умножаются на ноль и суммируются только нужные заказы.

Ссылки по теме

 

www.planetaexcel.ru

Excel выбрать из массива - Офис Ассист

Доброго времени суток друзья!

Сегодня я бы хотел затронуть тему массивов, так как частенько возникает ситуация, когда нужно найти значение в большом массиве данных. Для этих целей в Excel существует целый раздел функции для работы с массивами, которые помогают нам выполнять работы с массивами, но сейчас мы рассмотрим самые распространенные.

Обратите внимание, на эти функции, так как работа с огромными массивами данных, одна из самых распространенных и правильное использование этих функциипозволит вам значительно упростить и облегчить работу с таблицами Excel.

Ну, что же, изучим необходимые функции для работы с массивами:

1. Функция ВЫБОР (CHOOSE)

Позволит вам выбрать значение из общего списка по указанному номеру позиции:

=ВЫБОР(2;»Стул»;»Стол»;»Шкаф»;»Диван«)

2. Функция ИНДЕКС (INDEX)

Эта функция возвращает указанное значение из одно- или двумерного диапазона:

=ИНДЕКС(A1:C6;4;3)

Как видно с примера, полученное значение 37, в указанном диапазоне стоит на пересечении строки № 4 и столбика № 3 в диапазоне A1:C6 указанном в формуле. В более простом примере показано как в диапазоне С1:С6, на 2 месте находится значение 15:

=ИНДЕКС(С1:С6;2)

3. Функция ПОИСКПОЗ (MATCH)

Эта функция вернет позицию значения, которое вы будете искать в указанном диапазоне:

=ПОИСКПОЗ(B3;B2:B5;0)

С примера вы можете видеть что слово «Стол» занимает 2 позицию в указанном диапазоне. Замечу, что третий аргумент в функции не является обязательным. При введенном значении 0, функция вернет ту позицию элемента массива, которое точно совпадает со значением, которое мы ищем. В случае, когда точное совпадение отсутствует, функция выдаст ошибку #Н/Д (#N/A).

4. Функция ГПР (HLOOKUP)

Ищет значение в указанном диапазоне и возвращает значение ячейки, которая находится в указанной строке того же столбца: =ГПР(C1;$B$1:$E$2;1;ЛОЖЬ). Как видите с примера, функция ГПР ищет в указанном диапазоне $B$1:$E$2 (знаком $ я указал абсолютную ссылку) и согласно условию возвращает искомое значение из первой строки, а аргумент «ЛОЖЬ» означает, что-либо, будет найдено нужное значение, либо мы получим ошибку #Н/Д.

5. Функция ВПР (VLOOKUP)

Во многом, даже очень во многом, похожа на функцию ГПР, но используется не для горизонтальных массивов, а вертикальных, что наиболее распространено в использовании.

=ВПР(B4;$B$2:$C$5;2;ЛОЖЬ)

Как видим, формула идентична предыдущей функции ГПР и так же ищет указанный номер «B4» в диапазоне $B$2:$C$5 со знаком $ (это сделано для создания абсолютной ссылки, что бы при копировании формулы на диапазон, аргумент не будет изменен), в третьем столбце, так как аргумент функции равен 2. Ну и четвёртый аргумент равен значению «ЛОЖЬ», это означает, что-либо будет найдено совпадение значений, либо будет получено сообщение об ошибке #Н/Д. Теперь при необходимости, мы копируем формулу, и она перенесёт все правильные аргументы по всему диапазону вычислений. Это возможно стало из-за абсолютной ссылки на массив значений, а вот первый аргумент на B4, при копировании, должен измениться на B5 и так далее.

officeassist.ru

5 основных функции для работы с массивами

     Доброго времени суток друзья!

    Сегодня я бы хотел затронуть тему массивов, так как частенько возникает ситуация, когда нужно найти значение в большом массиве данных. Для этих целей в Excel существует целый раздел функции для работы с массивами, которые помогают нам выполнять работы с массивами, но сейчас мы рассмотрим самые распространенные.

     Обратите внимание, на эти функции, так как работа с огромными массивами данных, одна из самых распространенных и правильное использование этих функции позволит вам значительно упростить и облегчить работу с таблицами Excel.

     Ну, что же, изучим необходимые функции для работы с массивами:

     Позволит вам выбрать значение из общего списка по указанному номеру позиции:

           =ВЫБОР(2;"Стул";"Стол";"Шкаф";"Диван")

      Эта функция возвращает указанное значение из одно- или двумерного диапазона:

       =ИНДЕКС(A1:C6;4;3)

     Как видно с примера, полученное значение 37, в указанном диапазоне стоит на пересечении строки №4 и столбика №3 в диапазоне A1:C6 указанном в формуле. В более простом примере показано как в диапазоне С1:С6, на 2 месте находится значение 15:

       =ИНДЕКС(С1:С6;2)

     Эта функция вернет позицию значения, которое вы будете искать в указанном диапазоне:  

         =ПОИСКПОЗ(B3;B2:B5;0)

    С примера вы можете видеть что слово «Стол» занимает 2 позицию в указанном диапазоне. Замечу, что третий аргумент в функции не является обязательным. При введенном значении 0, функция вернет ту позицию элемента массива, которое точно совпадает со значением, которое мы ищем. В случае, когда точное совпадение отсутствует, функция выдаст ошибку #Н/Д (#N/A).

     Ищет значение в указанном диапазоне и возвращает значение ячейки, которая находится в указанной строке того же столбца:  =ГПР(C1;$B$1:$E$2;1;ЛОЖЬ). Как видите с примера, функция ГПР ищет в указанном диапазоне $B$1:$E$2 (знаком $ я указал абсолютную ссылку) и согласно условию возвращает искомое значение из первой строки, а аргумент «ЛОЖЬ» означает, что-либо, будет найдено нужное значение, либо мы получим ошибку #Н/Д.

     Во многом, даже очень во многом, похожа на функцию ГПР, но используется не для горизонтальных массивов, а вертикальных, что наиболее распространено в использовании.

         =ВПР(B4;$B$2:$C$5;2;ЛОЖЬ)

      Как видим, формула идентична предыдущей функции ГПР и так же ищет указанный номер «B4» в диапазоне $B$2:$C$5 со знаком $ (это сделано для создания абсолютной ссылки, что бы при копировании формулы на диапазон, аргумент не будет изменен), в третьем столбце, так как аргумент функции равен 2. Ну и четвёртый аргумент равен значению «ЛОЖЬ», это означает, что-либо будет найдено совпадение значений, либо будет получено сообщение об ошибке #Н/Д. Теперь при необходимости, мы копируем формулу, и она перенесёт все правильные аргументы по всему диапазону вычислений. Это возможно стало из-за абсолютной ссылки на массив значений, а вот первый аргумент на B4, при копировании, должен измениться на B5 и так далее.

     А на этом у меня всё! Я очень надеюсь, что описание 5 основных функций для работы с массивами вам стали ближе и понятнее. Буду очень благодарен за оставленные комментарии, так как это показатель читаемости и вдохновляет на написание новых статей! Делитесь с друзьями прочитанным и ставьте лайк!

     Не забудьте поблагодарить автора! 

Деньги для людей умных составляют средство, для глупцов — цель. А. Декурсель

Статья помогла? Поделись ссылкой с друзьями, твитни или лайкни!

topexcel.ru

Как выбрать из массива(массива(массива)) отдельные данные и записать в mysql?

Суть вопроса:
Есть данные обработанные json_decode() сразу вопрос: это строка или объекты?:
Данные
stdClass Object ( [data] => Array ( [0] => stdClass Object ( [id] => 216710 [name] => Офис [parent_id] => 0 [depth_level] => 1 ) [1] => stdClass Object ( [id] => 216878 [name] => Бумага для оргтехники [parent_id] => 216710 [depth_level] => 2 ) [2] => stdClass Object ( [id] => 216879 [name] => Бумага белая классов А, В, С [parent_id] => 216878 [depth_level] => 3 ) [3] => stdClass Object ( [id] => 216887 [name] => Бумага белая премиум класса [parent_id] => 216878 [depth_level] => 3 ) [4] => stdClass Object ( [id] => 216888 [name] => Бумага с магнитным слоем [parent_id] => 216878 [depth_level] => 3 ) [5] => stdClass Object ( [id] => 216889 [name] => Бумага для переноса изображения на ткань [parent_id] => 216878 [depth_level] => 3 ) [6] => stdClass Object ( [id] => 216882 [name] => Бумага цветная офисная [parent_id] => 216878 [depth_level] => 3 ) [7] => stdClass Object ( [id] => 216880 [name] => Бумага писчая [parent_id] => 216878 [depth_level] => 3 ) [8] => stdClass Object ( [id] => 216881 [name] => Бумага перфорированная [parent_id] => 216878 [depth_level] => 3 ) [9] => stdClass Object ( [id] => 216890 [name] => Бумага для чертежных и копировальных работ [parent_id] => 216878 [depth_level] => 3 ) [10] => stdClass Object ( [id] => 216891 [name] => Бумага копировальная (копирка) [parent_id] => 216890 [depth_level] => 4 ) [11] => stdClass Object ( [id] => 216894 [name] => Бумага масштабно-координатная [parent_id] => 216890 [depth_level] => 4 ) [12] => stdClass Object ( [id] => 216892 [name] => Ватман [parent_id] => 216890 [depth_level] => 4 ) [13] => stdClass Object ( [id] => 216893 [name] => Калька [parent_id] => 216890 [depth_level] => 4 ) [14] => stdClass Object ( [id] => 216884 [name] => Бумага для широкоформатной печати [parent_id] => 216878 [depth_level] => 3 ) [15] => stdClass Object ( [id] => 216885 [name] => Рулоны для принтера [parent_id] => 216878 [depth_level] => 3 ) [16] => stdClass Object ( [id] => 216886 [name] => Рулоны для факсов [parent_id] => 216878 [depth_level] => 3 ) [17] => stdClass Object ( [id] => 216895 [name] => Рулоны для касс, банкоматов и терминалов [parent_id] => 216878 [depth_level] => 3 ) [18] => stdClass Object ( [id] => 216898 [name] => Рулоны для касс из термобумаги [parent_id] => 216895 [depth_level] => 4 ) [19] => stdClass Object ( [id] => 216897 [name] => Рулоны для касс офсетные [parent_id] => 216895 [depth_level] => 4 ) [20] => stdClass Object ( [id] => 216899 [name] => Рулоны для терминалов и банкоматов из термобумаги [parent_id] => 216895 [depth_level] => 4 ) [21] => stdClass Object ( [id] => 216900 [name] => Дизайн- и сертификат-бумага [parent_id] => 216878 [depth_level] => 3 )))


Из этих данных нужно только id и parent_level.
записать в базу данных:

Соответственно в category_id и parent_id.
Помогите, пожалуйста, составить php

Мне так же потом придется делать для товаров, по этому если вас не затруднит, комментируйте, ваш код.

qna.habr.com

Ruby/Подробнее о массивах — Викиучебник

Подробнее о массивах[править]

Массивы — это тип данных, с которым вам придётся работать постоянно. Облик большинства программ зависит именно от правильного (читай: «изящного») использования массивов.

Способы создания массива[править]

Массив создаётся как минимум тремя способами. Первый способ:

Вы просто перечисляете элементы массива через запятую, а границы массива обозначаете квадратными скобками. С таким методом создания массива мы уже встречались. А теперь попробуем второй способ, через вызов метода .new класса Array:

Array.new(6){ |index| index + 1 } #=> [1, 2, 3, 4, 5, 6] 

Параметром метода .new является количество элементов будущего массива (в данном случае это число 6). В фигурных скобках указано, как мы будем заполнять массив. В данном случае значение элемента массива будет больше на единицу его индекса. Третий способ заключается в создании объекта типа Range (диапазон) и вызове метода .to_a:

(1..6).to_a #=> [1, 2, 3, 4, 5, 6] 

Есть ещё много способов, но эти три используются чаще всего.

Диапазоны[править]

Методом to_a очень удобно создавать из диапазона массив, содержащий упорядоченные элементы данного диапазона.

(1..10).to_a #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ("a".."d").to_a #=> ["a", "b", "c", "d"] 

Раз уж речь зашла о диапазонах, то давайте посмотрим, как они позволяют получать подмассивы. И насколько изящно у них это получается. Рассмотрим массив:

["a", "b", "c", "d", "e"] 

Традиционно нумерация массива начинается с нуля и возрастает по одному:

["a"0{\displaystyle {}^{0}}, "b"1{\displaystyle {}^{1}}, "c"2{\displaystyle {}^{2}}, "d"3{\displaystyle {}^{3}}, "e"4{\displaystyle {}^{4}}]

Такая нумерация называется в Ruby положительной индексацией. «Хм, — скажете вы, — а есть ещё и отрицательная?» Да, есть!

["a"−5+0{\displaystyle {}_{-5}^{+0}}, "b"−4+1{\displaystyle {}_{-4}^{+1}}, "c"−3+2{\displaystyle {}_{-3}^{+2}}, "d"−2+3{\displaystyle {}_{-2}^{+3}}, "e"−1+4{\displaystyle {}_{-1}^{+4}}]

Плюсы расставлены лишь для красоты. Но вернёмся к отрицательной индексации. Каков её смысл? Чтобы его пояснить, давайте решим задачку: дан массив, требуется получить предпоследний элемент.

array = ["a", "b", "c", "d", "e"] array[array.size - 2] #=> "d" 

В данном случае мы использовали метод .size, который возвращает размер массива. Разработчики заметили, что вызов array.size приходится писать довольно часто, и решили от него избавиться. Вот что получилось:

array = ["a", "b", "c", "d", "e"] array[-2] #=> "d" 

Индекс -2 значит «второй с конца элемент массива». Вот так и появилась отрицательная индексация. Теперь давайте разберёмся с диапазонами. Оказывается, в них тоже можно использовать отрицательную индексацию. Вот как можно получить все элементы массива кроме первого и последнего:

array = ["a", "b", "c", "d", "e"] array[1..-2] #=> ["b", "c", "d"] 

Или так:

array = ["a", "b", "c", "d", "e"] array[1...-1] #=> ["b", "c", "d"] 

Второй вариант с тремя точками, что автоматически приближает правую границу диапазона на одну позицию влево.

О двумерных массивах[править]

Для Ruby двумерный массив — это не более чем массив, содержащий одномерные массивы. Вот несколько примеров двумерных массивов:

[[1], [2, 3], [4]] # разная длина элементов-массивов [[1, 2], [3, 4]] # одинаковая длина [["прива", "Привет"], ["пока", "Всего хорошего"]] # двумерный массив (классика) [["прива", "Привет"], [1, ["пока", "Всего хорошего"]]] # гибрид двух-трёх-мерного массива 
  • Двумерность массива средствами языка не отслеживается. Вполне могут возникнуть гибриды разномерных массивов.
  • Подмассивы внутри двумерного массива могут иметь произвольную длину.
  • Элементы из двумерного массива достаются последовательно: сначала элемент-массив, потом элемент.

Методы работы с массивами[править]

Разнообразие и полезность методов у массивов создаёт впечатление, что все сложные алгоритмы уже реализованы. Это не так, но программистам Ruby дана действительно обширная библиотека методов. Здесь мы рассмотрим лишь самые употребимые, остальные ищите в справочнике.

Получение размера массива[править]

В Ruby массивы динамические: в каждый конкретный момент времени неизвестно, сколько в нём элементов. Чтобы не плодить тайн подобного рода и был реализован метод .size:

[1, "считайте", 3, "количество", 5, 6, "запятых", 2, 5].size #=> 9 

Мы явно указали массив, но на его месте могла стоять переменная:

array = [1, "считайте", 3, "количество", 5, 6, "запятых", 2, 5] array.size #=> 9 

Метод .size есть у многих классов. Например, у ассоциативных массивов и строк. И даже у целых чисел.

Поиск максимального/минимального элемента[править]

Вспомните сколько усилий вам приходилось прилагать, чтобы найти максимальный элемент? А сколько раз вы повторяли этот кусок кода в своих программах? Ну а в Ruby поиск максимального элемента осуществляется при помощи метода .max, а в более сложных случаях при помощи метода .max_by. Вот как это выглядит:

["у", "попа", "была", "собака"].max #=> "у" максимальный по значению ["у", "попа", "была", "собака"].max_by{ |elem| elem.size } #=> "собака" максимальный по размеру строки 

Методы .min и .min_by работают аналогично:

["у", "попа", "была", "собака"].min #=> "была" минимальный по значению ["у", "попа", "была", "собака"].min_by{ |elem| elem.size } #=> "у" минимальный по размеру строки 

Ну как? А в Ruby эти методы уже давно.

Упорядочение[править]

Чтобы упорядочить массив, нужно вызвать метод .sort или .sort_by (начиная с версии 1.8).

["у", "попа", "была", "собака"].sort #=> ["была", "попа", "собака", "у"] сортировка по значению ["у", "попа", "была", "собака"].sort_by{ |elem| elem.size } #=> ["у", "попа", "была", "собака"] сортировка по размеру строки 

Для двумерных массивов:

 [[1,0], [16,6], [2,1], [4,5],[4,0],[5,6]].sort_by {|elem| elem[1]} #=> [[1, 0], [4, 0], [2, 1], [4, 5], [16, 6], [5, 6]] сортировка "внешних" элементов по значению "внутренних" [[1,0], [16,6], [2,1], [4,5],[4,0],[5,6]].sort_by {|elem| elem[0]} #=> [[1, 0], [2, 1], [4, 0], [4, 5], [5, 6], [16, 6]] 

Остается только добавить, что массивы упорядочиваются по возрастанию. Если вам надо по убыванию, то придётся писать собственный метод сортировки пузырьком. Шутка! По правде же, есть много способов выстроить массив по убыванию. Пока мы будем использовать метод .reverse, обращающий массив.

Обращение массива[править]

Обращение массива — это изменение порядка элементов на обратный, то есть первый элемент становится последним, второй элемент — предпоследним и так далее.

Для обращения массива существует метод .reverse. Применим его к предыдущим примерам, чтобы получить сортировку по убыванию:

["у", "попа", "была", "собака"].sort.reverse #=> ["у", "собака", "попа", "была"] ["у", "попа", "была", "собака"].sort_by{ |elem| elem.size }.reverse #=> ["собака", "была", "попа", "у"] 

Метод .reverse мы просто прицепили в конец предыдущего примера. Так можно выстроить произвольную цепочку допустимых методов; выполняться они будут по очереди, начиная с самого левого, то есть самого первого в цепочке.

Сложение/вычитание массивов[править]

Для сложения массивов, строк и чисел используется метод +:

[1, 2, 3, 4] + [5, 6, 7] + [8, 9] #=> [1, 2, 3, 4, 5, 6, 7, 8, 9] 

Плюс берёт массив справа и, будто это железнодорожный состав, прицепляет его к хвосту первого массива. Это называется конкатенацией.

Вычитаются массивы методом -, но происходит это сложнее, чем расцепление вагонов:

[1, 1, 2, 2, 3, 3, 3, 4, 5] - [1, 2, 4] #=> [3, 3, 3, 5] 

Из первого массива удаляются все элементы, имеющиеся во втором, независимо от их количества. Остальные элементы остаются без изменений, сохраняют относительные позиции.

Объединение и пересечение массивов (как множеств)[править]

Очень часто приходится решать задачи, в которых нужно оперировать множествами. У массивов припасено для этих целей два метода: | (объединение) и & (пересечение).

Рассмотрим объединение множеств в действии:

[1, 2, 3, 4, 5, 5, 6] | [0, 1, 2, 3, 4, 5, 7] #=> [1, 2, 3, 4, 5, 6, 0, 7] 

Объединение получается вот так. Сначала массивы сцепляются:

[1, 2, 3, 4, 5, 5, 6, 0, 1, 2, 3, 4, 5, 7] 

Затем, начиная с первого вагона, инспектор идёт от вагона к вагону, удаляя элементы, которые уже встречались. После зачистки получается настоящее логическое объединение.

На деле это выглядит так:

[1, 2, 3, 4, 5, -5-, 6, 0, -1-, -2-, -3-, -4-, -5-, 7] 

Зачёркнутые числа — это удаленные элементы (дубликаты). Переходим от слов к делу:

[1, 2, 3, 4, 5, 5, 6] & [0, 2, 1, 3, 5, 4, 7] #=> [1, 2, 3, 4, 5] 

При пересечении двух массивов, из первого удаляются все элементы, отсутствующие во втором. А из второго, отсутствующие в первом. При этом относительный порядок остающихся элементов первого массива сохраняется.

[1, 2, 3, 4, 5, -5-, -6-] & [-0-, 2, 1, 3, 5, 4, -7-] 

Всё просто. Важно лишь помнить, что | и & не изменяют ни первый, ни второй исходные массивы. Они через описанные процедуры создают новый массив. Чтобы тот не уехал от вас, нужно присвоить его; но не себе, а переменной, приготовленной слева от =.

В итоге пересечения или объединения множеств получается массив, не содержащий дубликатов.

Удаление дубликатов[править]

Для удаления дубликатов (повторяющихся элементов массива) в Ruby используется метод .uniq:

[1, 2, 3, 4, 5, 5, 6, 0, 1, 2, 3, 4, 5, 7].uniq #=> [1, 2, 3, 4, 5, 6, 0, 7] 

Процесс зачистки массива от дубликатов такой же, как и в объединении.

[1, 2, 3, 4, 5, -5-, 6, 0, -1-, -2-, -3-, -4-, -5-, 7] 

Поэтому объединение массивов можно записать как

Но проще, конечно, объединять палкой.

Сплющивание массивов[править]

Метод .flatten делает из многомерного массива простой, длинный одномерный массив. Он как бы расплющивает его. Например, чтобы найти в двумерном массиве наибольший элемент, мы сперва расплющим массив, а потом найдём максимум методом .max:

array = [[1, 2], [3, 4]] array.flatten.max #=> 4 

Расплющивание происходит в несколько этапов. Сначала происходит удаление всех квадратных скобок.

-[[- 1, 2 -]-, -[- 3, 4 -]]- 

А потом, две квадратные скобки добавляются слева и справа. Но делать это надо быстро, чтобы элементы не успели разбежаться.

Вот и всё! У нас они разбежаться не успели. Повторите данное упражнение на других массивах (двумерных, трёхмерных и так далее).

Удаление неопределённых (nil) элементов[править]

Функцию удаления элементов nil массива выполняет метод .compact например:

array = [1, nil, 2, nil, 3] array.compact #=> [1, 2, 3] 
Транспонирование двумерного массива[править]

Задача: дан двумерный массив. Вывести одномерный массив с максимумами каждого из столбцов. Хм… посмотрим сперва, как эта задача решается для строчек, а не столбцов:

array2D = [[1, 2], [3, 4]] array2D.map{ |array| array.max } #=> [2, 4] 

Метод .map — это итератор, который позволяет нам делать что-нибудь с каждым объектом, на который указывает массив. Подробнее о них ниже в этой главе.

Чтобы решить задачу в первоначальном варианте, нам надо лишь предварительно транспонировать массив (поменять местами строки и столбцы):

array2D = [[1, 2], [3, 4]] array2D.transpose.map{ |array| array.max } #=> [3, 4] 

Метод .transpose как раз и занимается транспонированием. Это позволяет с лёгкостью решать задачи про столбцы приёмами, схожими с задачами про строки.

Размножение массивов[править]

Речь пойдёт не о почковании, а о методе, который позволяет умножать массив на целое число. В результате такого умножения мы получим массив, состоящий из нескольких копий элементов исходного массива.

["много", "денег", "прячет", "тёща"] * 2 #=> ["много", "денег", "прячет", "тёща", "много", "денег", "прячет", "тёща"] 

Того же самого эффекта можно добиться сцепив массив необходимое количество раз:

array = ["много", "денег", "прячет", "тёща"] array + array #=> ["много", "денег", "прячет", "тёща", "много", "денег", "прячет", "тёща"] 

Заметили, что есть некоторая параллель с целыми числами? Умножение можно заменить сложением и наоборот!

Функциональность стека[править]

Часто и во многих алгоритмах надо добавить элемент в конец массива:

array = [1, 2, 3, 4, 5] array[array.size] = 6 array #=> [1, 2, 3, 4, 5, 6] 

И если уж добавили, то надо как-то его и удалить. Делается это примерно так:

array = [1, 2, 3, 4, 5, 6] array[0...-1] #=> [1, 2, 3, 4, 5] 

Но как всегда, эти задачи возникали слишком часто и их решили реализовать в виде методов. Методы назвали .push («втолкнуть» в конец массива) и .pop («вытолкнуть» элемент из массива):

array = [1, 2, 3, 4, 5] array.push(6) array #=> [1, 2, 3, 4, 5, 6] array << 7 #=> [1, 2, 3, 4, 5, 6, 7], другой синтаксис array.pop #=> 7 array #=> [1, 2, 3, 4, 5, 6] 
Функциональность очереди и списка[править]

Чтобы можно было использовать массив в качестве очереди и/или списка, потребуется сделать всего лишь пару методов. Первый из них добавляет элемент в начало массива, а второй удаляет элемент из начала. Давайте посмотрим, как это делается универсальными методами [], []= и +:

array = [1, 2, 3, 4, 5] # добавим элемент в начало массива # способ № 1 array = [6] + array array #=> [6, 1, 2, 3, 4, 5] array[0] #=> 6 # способ № 2 array[1..array.size] = array[0..-1] #=> [1, 1, 2, 3, 4, 5] array[0] = 6 array #=> [6, 1, 2, 3, 4, 5] # удалим элемент из начала массива array = array[1..-1] array #=> [1, 2, 3, 4, 5] 

Теперь посмотрим, какие методы реализуют точно такую же функциональность:

array = [1, 2, 3, 4, 5] # добавляем элемент в начало массива array.unshift(6) #=> [6, 1, 2, 3, 4, 5] # удаляем из начала массива array.shift #=> 6 array #=> [1, 2, 3, 4, 5] 

Удаляющий метод — .shift («сдвинуть»), а метод, добавляющий элемент в начало массива, называется .unshift (непереводимое слово, означающее нечто противоположное «сдвинуть обратно»).

Мнемограмма для методов стека/очереди/списка[править]

Мнемограмма для методов .shift, .unshift, .pop и .push:

.unshift(0) .push(6) [1, 2, 3, 4, 5] .shift .pop 

Методы с параметром (сверху) добавляют элемент в массив, а методы без параметра (снизу) — удаляют. По желанию можно дорисовать стрелочки.

Метод .shift сдвигает влево,
Метод .pop — направо.
Метод .push к концу цепляет,
А .unshift — к началу.

Замечание. Имена методов unshift/shift неинтуитивны. Во-первых, они не напоминают о том, что работа идёт с головой массива, а не с хвостом, во-вторых ничего не говорят о том, идёт заполнение или опустошение стека. Можно создать для этих методов псевдонимы с говорящими именами, например, feed/spit (кормить/выплевывать):

class Array alias feed :unshift alias spit :shift end 
Создание своих классов, работающих как массивы[править]

Если потребуется написание своего класса, который работает, как описанные массивы, то возникают некоторые тонкости. Дело в том, что реализация всех описанных методов займёт жуткое количество времени и сил. На самом деле, для реализации большинства описанных методов, достаточно реализовать .each.

Где это может понадобиться? Например, вы реализуете класс, который умеет читать из файла записи определённой структуры. Основную его логику занимает именно чтение нужного формата, кеширование, разбор, десериализация и тому подобное.

Просто реализуйте .each и включите в ваш класс примесь Enumerable. В нём находится реализация методов, таких как .inject, .each_with_index и тому подобные.

Логические методы[править]

Логический метод — это метод, результатом которого является логическое выражение (true или false).

По японской традиции, имена логических методов принято заканчивать ? (вопросительным знаком). Это позволяет также получить список логических методов, вызываемых в данном случае: просто отобрать из всех имеющихся методов те, что кончаются на ?. Делается это при помощи небольшой вспомогательной программы:

array = [1, 2, 2, 3] puts array.methods.grep(/\?$/) 

Для удобства, можно упорядочить полученный список:

array = [1, 2, 2, 3] puts array.methods.grep(/\?$/).sort 
Есть ли элемент в массиве?[править]

Как узнать, есть ли некоторый элемент в массиве? Попробуем решить эту задачу при помощи метода .size и итератора .find_all:

array = [1, 2, 3, 4, 5, 6, 7] required = 5 # число, которое мы будем искать array.find_all{ |elem| elem == required }.size != 0 #=> true # это значит, что такое число есть 

Использование связки из трёх методов (!=, .find_all и .size) для такой задачи — возмутительно! Разработчики не могли с этим долго мириться и реализовали метод специально для этой задачи. Имя ему — .include?. Перепишем нашу задачу, но на этот раз будем использовать правильный метод:

array = [1, 2, 3, 4, 5, 6, 7] required = 5 # число, которое мы будем искать array.include?(required) #=> true # что бы это значило? 

Мутный горизонт скрывает берег,
Ветер мокр, холоден и лют.
Есть ли в озере акулы, я проверю
Методом логическим .include?.

lake = ["правый берег", "ветер", "вода", "вода", "вода", "окунь", "вода", "вода", "левый берег"] lake.include?("акула") #=> false 

Опытным путём мы доказали, что акулы в озере не водятся.

Массив пустой?[править]

Если вы хотите задать массиву вопрос «пуст ли ты?», но боитесь обидеть, то можете пойти окружным путём. Например, спросить у него: ты равен пустому массиву?

empty_array = [] filled_array = [1, 2, 2, 3] empty_array == [] #=> true filled_array == [] #=> false 

Ещё можно задать вопрос: твой размер равен нулю?

empty_array = [] filled_array = [1, 2, 2, 3] empty_array.size == 0 #=> true filled_array.size == 0 #=> false 

Но наш вам совет: не стоит искать обходных путей. Спросите его напрямую: .empty? («пуст?»):

empty_array = [] filled_array = [1, 2, 2, 3] empty_array.empty? #=> true filled_array.empty? #=> false 
И наоборот[править]

В Ruby принято избегать отрицания условия. Например, если вам нужно сделать что-то, если массив не пуст, можно воспользоваться методом, обратным empty?. Этот метод называется any?.

array = [1, 2, 4] array.length > 0 #=> true array.empty? #=> false array.any? #=> true 

Итераторы[править]

Массивы — эти эшелоны переменных, эти ожерелья запятых и элементов — часто приходится проходить целиком, обследуя каждый элемент. Да и не только массивы, но и любые последовательности чего-нибудь.

В старину люди делали это циклами. В Ruby у списочных структур данных есть встроенные методы, которые проходят весь ряд поэлементно, но, в отличие от циклов:

  • не зацикливаются: счётчик цикла нельзя докручивать;
  • выполняются заведомое число раз;
  • их много, и каждый делает своё дело.

Имя им — итераторы.

Изменение всех элементов массива[править]

Изменить все элементы массива можно по-всякому. Начнём с обнуления:

array = ["шифровка", "Штирлица", "в", "Центр", "секретно"] array.map{ 0 } #=> [0, 0, 0, 0, 0] 

В приведенном примере каждый элемент массива будет заменён нулем независимо от того, чем является этот элемент. Например, при попытке обнулить таким образом двумерный массив [[1, 2], [3, 4]], в результате получим [0, 0].

Используется итератор .map, за которым следует замыкание, — кусочек кода, схваченный лапками-фигурными скобками. .map последовательно проходит array и выполняет замыкание заново для каждого элемента. То, что выходит из замыкания, итератор .map делает очередным элементом нового массива.

Можно дать элементу .map иное задание. Для этого зажимаем в фигурные скобы замыкания иной код:

array = [1, 2, 3, 4, 5] array.map{ |elem| elem ** 2 } #=> [1, 4, 9, 16, 25] 

Прежде, чем замыканию выдать квадрат очередного элемента, ему нужно знать этот элемент. Итератор .map даёт ему значение элемента, словно фотографию, обрамлённую слева и справа вертикальными чертами |. Чтобы замыкание смогло взять эту фотографию, обязательно нужно дать ей имя. В нашем случае это elem, но подходят и такие названия:

Но недопустимы названия вроде Like_This или 3This. Правила именования тут такие же, как и для обычных переменных.

Вы уже, наверное, хорошо поняли, что в итераторах массивы обрабатываются по очереди; двери вагона расходятся, появляется элемент. Замыкание даёт ему прозвище, выполняет код в лапках-фигурных скобках. Затем переходит к следующему вагону, и там всё сначала.

Но ещё важно помнить, что элементы не уходят из первого вагона: замыкание лишь осматривает каждый элемент, берёт его значение, но не меняет. Всё, что получается в результате работы замыкания, садится в очередной вагон другого поезда.

То имя, что показывается в раздвижных дверях, — это не сам элемент, это лишь его копия. Фотография. Голограмма. Это даже не другая переменная, это не переменная вообще. Бессмысленно присваивать новое значение фотографии:

array = [1, 2, 3, 4, 5] array.map{ |elem| elem = elem**2 } # присваивание не имеет смысла: elem несёт лишь значение элемента, не являясь им 

Из итератора .map выезжает другой поезд, у которого вместо соответствующего элемента первого поезда сидит результат вычисления замыкания. Используйте этот массив как-нибудь, иначе поезд уедет.

array = [1, 2, 3, 4, 5] array.map{ |elem| elem**2 } #=> [1, 4, 9, 16, 25] array #=> [1, 2, 3, 4, 5] — неизменный первый поезд 

Можно присвоить его новой переменной array_of_squares. А можно заместить им существующую переменную array:

array = [1, 2, 3, 4, 5] array = array.map{ |elem| elem**2 } #=> [1, 4, 9, 16, 25] array #=> [1, 4, 9, 16, 25] 

Это общее явление Ruby: методы (здесь — итераторы) не меняют объект (массив), с которым работают. Они лишь выдают результат, который потом можно использовать как аргумент или присвоить переменной.

Явление было воспето в фольклоре:

Метод .map всё изменяет,
Как кто пожелает
И обижается на тех,
Кто результат не сохраняет.

Для того, чтобы сохранить результат выполнения метода в исходную переменную, нужно добавить к названию метода восклицательный знак.

array = [1, 2, 3, 4, 5] array.map!{ |elem| elem**2 } #=> [1, 4, 9, 16, 25] array #=> [1, 4, 9, 16, 25] 

Такой приём работает и с многими другими методами в языке, которые только возвращают результат своего выполнения. Однако при использовании цепочек методов каждый должен быть с восклицательным знаком, иначе разорвётся цепочка копирований.

array = [1, 2, 3, 4, 5, nil] array.compact.map!{ |elem| elem**2 } #=> [1, 4, 9, 16, 25] array #=> [1, 2, 3, 4, 5, nil] array.compact!.map!{ |elem| elem**2 } #=> [1, 4, 9, 16, 25] array #=> [1, 4, 9, 16, 25] 

В первом случае операция .compact создала копию массива, тогда как .compact! заменила первоначальные значения результатами, полученными от .map!

Отбор элементов по признаку[править]

Вот как итератор .find_all выберет из массива все чётные элементы:

array = [1, 2, 3, 4, 5] array.find_all{ |elem| elem % 2 == 0 } #=> [2, 4] 

elem % 2 == 0 — это вопрос «чётен ли elem?». Ответом, как всегда, будет true или false. Ведь «чётность» — это равенство нулю (== 0) остатка деления (%) на 2.

Кстати, равенство нулю можно проверять и при помощи метода .zero?. А чётность тоже можно проверить разными способами:

(elem % 2).zero? (elem & 1).zero? (elem[0]).zero? # Этот вариант круче всех 

Если на вопрос, заданный в замыкании, ответ true, то |elem| (значение очередного элемента исходного массива), заносится в новый массив, который в итоге будет выводом из итератора .find_all.

Выражение в замыкании для .find_all должно быть логическим, то есть принимать значение true или false.

Если нужно элементы
По условию искать,
То полезнее .find_all
Метод вам не отыскать!

Также есть методы .odd? и .even? для более наглядной реализации таких вещей, нечетный и четный соответственно.

array = [1, 2, 3, 4, 5] array.find_all{ |elem| elem.even? } #=> [2, 4] 
Суммирование/произведение/агрегация элементов[править]

Очень часто возникает задача найти сумму/произведение всех элементов массива. Для этих целей традиционно используется итератор .inject. Для демонстрации его работы, давайте найдем сумму элементов массива:

array = [1, 2, 3, 4, 5] array.inject(0){ |result, elem| result + elem } #=> 15 

Рассмотрим все по порядку. Начнём с нуля. Его следует расшифровывать как result = 0 перед началом работы итератора, то есть это начальное значение переменной result (переменной промежуточного результата).

Далее идёт объявление двух переменных. Первая из них (result) будет хранить промежуточный результат. Вторая (elem) — фотография текущего элемента массива (или последовательности), мы такую уже видели.

После объявления описан алгоритм работы итератора. В данном случае ему предписано каждый элемент массива складывать с промежуточной суммой: result + elem.

  • Присваивание переменной (которая описывает промежуточную сумму или текущий элемент) внутри замыкания указывает на непонимание работы итератора .inject (и многих других). Вам должно быть стыдно!
  • Результат последнего вычисления автоматически запишется в переменную с промежуточным результатом.

Учитывая эти два замечания, напишем код, который является неправильным:

array = [1, 2, 3, 4, 5] array.inject(0){ |result, elem| result = result + elem } #=> 15 

Имена переменных result и elem созданы богатым воображением автора. В ваших программах они могут называться иначе.

Невероятно, но от изменения имён переменных результат не меняется. Помните это!

Для полноты картины решим ещё одну задачку. На этот раз будем искать произведение всех элементов массива:

array = [1, 2, 3, 4, 5] array.inject(1){ |result, elem| result * elem } #=> 120 

А вот так мо

ru.wikibooks.org

Массивы в языке 1С 8.3, 8.2 (в примерах)

/// Как создать массив (сразу нужного размера) в 1с 8.3, 8.2   &НаКлиенте Процедура Пример1(Команда)   // в массиве сразу 3 элемента Массив = Новый Массив(3);   // инициализируем их значениями Массив[0] = 5; Массив[1] = Массив[0] * 2; // 10 Массив[2] = Массив[1] * 2; // 20   // выводим на печать Для Каждого ЭлементМассива из Массив Цикл Сообщить(ЭлементМассива); // 5 10 20 КонецЦикла;   КонецПроцедуры   /// Как создать пустой массив (с последующим добавлением /// элементов) в 1с 8.3, 8.2   &НаКлиенте Процедура Пример2(Команда)   // в массиве 0 элементов Массив = Новый Массив;   // добавляем последовательно три элемента Массив.Добавить(100); // (100) Массив.Добавить(300); // (100, 300) Массив.Добавить(500); // (100, 300, 500)   // выводим на печать Для Каждого ЭлементМассива из Массив Цикл Сообщить(ЭлементМассива); // 100 300 500 КонецЦикла;   КонецПроцедуры   /// Как обойти все элементы массива по индексу в 1с 8.3, 8.2   &НаКлиенте Процедура Пример3(Команда)   // инициализируем массив: (100, 300, 500) Массив = Новый Массив; Массив.Добавить(100); Массив.Добавить(300); Массив.Добавить(500);   // пробегаемся от первого (с индексом 0) до последнего // элемента (с индексом Количество - 1). Для Индекс = 0 По Массив.Количество() - 1 Цикл Сообщить(Массив[Индекс]); КонецЦикла;   КонецПроцедуры   /// Массив может содержать элементы различных типов: числа, /// строки и т.д.   &НаКлиенте Процедура Пример4(Команда)   Массив = Новый Массив(4); Массив[0] = "HELP"; // ("HELP") Массив[1] = "ME"; // ("HELP", "ME") Массив[2] = "1C"; // ("HELP", "ME", "1C") Массив[3] = Формат(2013, "ЧГ=0"); // ("HELP", "ME", "1C", 2013)   Для Каждого ЭлементМассива из Массив Цикл Сообщить(ЭлементМассива); // HELP ME 1C 2013 КонецЦикла;   КонецПроцедуры   /// Как передать массив в качестве параметра функции в 1с 8.3, 8.2   &НаКлиенте Функция Метод5(массивПереданныйПоСсылке)   массивПереданныйПоСсылке[0] = 10; Возврат массивПереданныйПоСсылке[0] * 2;   КонецФункции   &НаКлиенте Процедура Пример5(Команда)   // инициализация массива из одного элемента: (13) Массив = Новый Массив(1); Массив[0] = 13;   // значение первого элемента до вызова функции Сообщить(Массив[0]); // 13   // массив ВСЕГДА передается в функцию ПО ССЫЛКЕ, значит, // изменяя массив внутри функции, мы меняем его снаружи Сообщить(Метод5(Массив)); // 20   // значение первого элемента после вызова функции изменилось Сообщить(Массив[0]); // 10   КонецПроцедуры   /// Как вернуть массив в качестве результата работы функции /// в 1с 8.3, 8.2   &НаКлиенте Функция Метод6()   // инициализация массива (СПАСИБО, ВАМ) массив = Новый Массив(2); массив[0] = "СПАСИБО"; массив[1] = "ВАМ";   Возврат массив;   КонецФункции   &НаКлиенте Процедура Пример6(Команда)   // инициализация переменной массивом, который возвращает и формирует // функция Метод6 Массив = Метод6();   // вывод на печать Для Каждого ЭлементМассива из Массив Цикл Сообщить(ЭлементМассива); // СПАСИБО ВАМ КонецЦикла;   КонецПроцедуры   /// Ещё пример на передачу массива в качестве параметра процедуры /// в 1с 8.3, 8.2   &НаКлиенте Процедура Метод7(Массив)   Если Массив <> Неопределено И Массив.Количество() > 0 Тогда Сообщить(Массив[0]); КонецЕсли;   КонецПроцедуры   &НаКлиенте Процедура Пример7(Команда)   // инициализация массива: (10, 20) Массив = Новый Массив(2); Массив[0] = 10; Массив[1] = 20;   // печать первого элемента, переданного массива Метод7(Массив); // 10 Метод7(Неопределено); // ничего Метод7(Новый Массив); // ничего   КонецПроцедуры   /// Как получить последний элемент массива в 1с 8.3, 8.2   &НаКлиенте Процедура Пример8(Команда)   // инициализация массива: ("Кошка", "Собака", "Пантера", "Тигр") Массив = Новый Массив; Массив.Добавить("Кошка"); Массив.Добавить("Собака"); Массив.Добавить("Пантера"); Массив.Добавить("Тигр");   Сообщить(Массив[Массив.Количество() - 1]); // Тигр   КонецПроцедуры   /// Использование многомерных массивов в 1с 8.3, 8.2   &НаКлиенте Процедура Пример9(Команда)   // ( ( (), () ), ( (), () ), ( (), () ) ) Массив = Новый Массив(3, 2);   // ( ( "Юрий", "Гагарин" ), ( (), () ), ( (), () ) ) Массив[0][0] = "Юрий"; Массив[0][1] = "Гагарин";   // ( ( "Юрий", "Гагарин" ), ( "Герман", "Титов" ), ( (), () ) ) Массив[1][0] = "Герман"; Массив[1][1] = "Титов";   // ( ( "Юрий", "Гагарин" ), ( "Герман", "Титов" ), // ( "Валентина", "Терешкова" ) ) Массив[2][0] = "Валентина"; Массив[2][1] = "Терешкова";   // обход всех элементов через конструкцию Для Каждого   Для Каждого Строка Из Массив Цикл Для Каждого Элемент Из Строка Цикл Сообщить(Элемент); КонецЦикла; Сообщить(" "); КонецЦикла;   Сообщить(" ");   // обход всех элементов через индекс   Для ИндексСтрока = 0 По Массив.Количество() - 1 Цикл Для ИндексСтолбец = 0 По Массив[ИндексСтрока].Количество() - 1 Цикл Сообщить(Массив[ИндексСтрока][ИндексСтолбец]); КонецЦикла; Сообщить(" "); КонецЦикла;   КонецПроцедуры   /// Вставка, удаление и очистка массива в 1с 8.3, 8.2   &НаКлиенте Процедура Пример10(Команда)   // инициализация пустого массива Массив = Новый Массив;   // вставка трёх элементов; каждый элемент вставляется в начало Массив.Вставить(0, 10); // (10) Массив.Вставить(0, 100); // (100, 10) Массив.Вставить(0, 1000); // (1000, 100, 10)   // определение последнего индекса Сообщить(Массив.ВГраница()); // 2   // вывод на печать Для Индекс = 0 по Массив.ВГраница() Цикл Сообщить(Массив[Индекс]); // 1000 100 10 КонецЦикла;   // удаление элемента со значением 100 // для этого сначала находим индекс элемента // если не находим возвращаем Неопределено Индекс = Массив.Найти(100); // 1 // и удаляем элемент по найденному индексу Массив.Удалить(Индекс); // (1000, 10)   Сообщить(Массив.ВГраница()); // 1   // удаление всех элементов из массива Массив.Очистить();   КонецПроцедуры   /// Как из обычного получить фиксированный (неизменяемый) /// массив в 1с 8.3, 8.2   &НаКлиенте Процедура Пример11(Команда)   Числа = Новый Массив; Числа.Добавить(1); Числа.Добавить(2); Числа.Добавить(3);   ФиксированныеЧисла = Новый ФиксированныйМассив(Числа); // Получился константный массив на основе обычного: // нельзя менять значения имеющихся элементов // нельзя добавлять новые элементы // нельзя удалять имеющиеся элементы   КонецПроцедуры   /// Скачать и выполнить эти примеры на компьютере

helpme1c.ru

Работа с массивом в 1С 8.3 на примерах

Объекты типа массив в 1С 8.3 представляют собой совокупность упорядоченных значений любого типа, в том числе и типа «массив», что в свою очередь позволяет организовывать многомерные массивы. Идентификация значений осуществляется по индексам, нумерация которых начинается с «0».

Создание массива

Синтаксис:

Новый Массив(<КоличествоЭлементов1>,…,<КоличествоЭлементовN>) 

Примеры:

//Одномерный массив
 ПустойМассив = Новый Массив();//Пустой массив
 
 Массив2 = Новый Массив(2);//массив из двух элементов
 
 //Двумерный массив в 1С 8.3
 ДвумерныйМассив = Новый Массив(2,3);//Каждый из двух элементов                      
 // двумерного массива является массивом
 // из трёх элементов
 
 //Фиксированный (неизменный) массив
 ФиксМассив = Новый ФиксированныйМассив(Массив2);                              
 

Добавление элементов в массив

Примеры:

Массив = Новый Массив();//Создадим массив для примера
 //Метод Добавить().Добавляет элемент в конец массива
 Массив.Добавить("знач1");//Добавили элемент с типом строка
 Массив.Добавить();//Добавили пустой элемент в массив
 

Результат:

//Метод Вставить().Вставляет значение в массив по индексу.
 Массив.Вставить(0);//Вставили пустой элемент в начало массива. Тем самым
 //произошла переиндексация всего массива. Элемент с индексом
 //[0] стал [1], [1] стал [2]
 

Результат:

Массив.Вставить(5,"знач6");//Вставили элемент со значением "знач6" по индексу [5].
 //По недостающим индексам [3] и [4], произошло добавление
 //пустых элементов

Результат:

Получение значения элемента по индексу

Массив.Получить(5);//В скобках указываем индекс (число) желаемого элемента
 ДвумерныйМассив.Получить(0).Получить(0);
 

Поиск в массиве 1С

Массив.Найти("знач6");//В скобках указываем значение искомого элемента
 

Присвоение значений элементам массива

Примеры:

Массив.Установить(0,10);//Присвоили ранее созданному элементу с
 // индексом [0] значение "10", тип число
 
 Массив[2] = "знач3";//Присвоили ранее созданному элементу с индексом [2]
 //значение "знач3", тип строка
 
 ДвумерныйМассив[0][0] = "ЗНАЧ";//Присвоили ранее созданному элементу
 //с индексом [0][0] значение "ЗНАЧ", тип строка
 

Как узнать количество элементов массива (размер массива)

Массив.ВГраница();//Получаем наибольший индекс элемента массива (число)
 Массив.Количество();//Получаем количество элементов в массиве (число)
 

Перебор массива 1С

Примеры:

//По индексу
 Для Индекс = 0 по Массив.ВГраница() Цикл
 Сообщить(Индекс);
 КонецЦикла;
 
 //По элементам
 Для Каждого Элемент Из Массив Цикл
 Сообщить(Элемент);
 КонецЦикла;
 

Перебор всех элементов двумерного массива

Примеры:

//По индексу
 Для ИндексСтр = 0 По ДвумерныйМассив.ВГраница() Цикл
 Для ИндексСтолбец = 0 По ДвумерныйМассив[ИндексСтр].ВГраница() Цикл
 Сообщить(ДвумерныйМассив[ИндексСтр][ИндексСтолбец]);
 КонецЦикла;
 КонецЦикла;
 
 //По элементам
 Для Каждого Строка Из ДвумерныйМассив Цикл
 Для Каждого Элемент Из Строка Цикл
 Сообщить(Элемент);
 КонецЦикла;
 КонецЦикла;        

Удаление элементов из массива

Примеры:

Получите 267 видеоуроков по 1С бесплатно:

//Удаление элемента из массива по индексу
 Массив.Удалить(3);//В скобках указываем индекс (число) удаляемого элемента
 
 //Удаление всех элементов из массива
 Массив.Очистить();
 

Как разложить строку в массив

&НаКлиенте
 Процедура СтрокуВ_Массив(Команда)
 
 МассивСтрок = Новый Массив;
 Строка = "Строку в массив";
 МассивСтрок = СтрРазделить(Строка, " ");
 
 КонецПроцедуры
 

Результат:

Пример преобразования массива в список значений

&НаКлиенте
 Процедура МассивВ_СписокЗначений(Команда)
 
 Массив = Новый Массив();
 Массив.Добавить("знач1");
 Массив.Добавить("знач2");
 Массив.Добавить("знач3");
 
 СЗ = Новый СписокЗначений;//Создаём список значений
 СЗ.ЗагрузитьЗначения(Массив);//Загрузка значений элементов массива в СЗ
 
 КонецПроцедуры
 

Результат:

Пример преобразования массива в таблицу значений

&НаКлиенте
 
 Процедура МассивВ_ТЗ(Команда)
 
 Массив = Новый Массив();
 Массив.Добавить(1);
 Массив.Добавить(2);
 Массив.Добавить(3);
 
 МассивВ_ТЗ_Сервер (Массив);
 
 КонецПроцедуры
 
 
 &НаСервере
 Процедура МассивВ_ТЗ_Сервер (Массив)
 
 ТЗ = Новый ТаблицаЗначений;//Создаём таблицу значений
 ТЗ.Колонки.Добавить("НаборЧисел");
 
 //Добавляем строки в ТЗ
 Для Индекс = 0 по Массив.ВГраница() Цикл
 НовСтрока = ТЗ.Добавить();
 КонецЦикла;
 
 ТЗ.ЗагрузитьКолонку(Массив,"НаборЧисел");//преобразуем в таблицу значений
 ТЗизМассива = ТЗ;//результат
 
 КонецПроцедуры
 

Результат:

Сортировка массива 1С разными способами

Примеры:

//Через список значений
 &НаКлиенте
 Процедура СортироватьМассивЧерезСЗ(Команда)
 
 Массив = Новый Массив();
 Массив.Добавить("знач1");
 Массив.Добавить("знач2");
 Массив.Добавить("знач3");
 
 СЗ = Новый СписокЗначений;//Создаём список значений
 СЗ.ЗагрузитьЗначения(Массив);//Загрузка значений элементов массива в СЗ
 СЗ.СортироватьПоЗначению(НаправлениеСортировки.Убыв);//Сортируем по убыванию
 СЗ.СортироватьПоЗначению(НаправлениеСортировки.Возр);//Сортируем по возрастанию
 
 Массив = СЗ.ВыгрузитьЗначения();//В массив
 
 КонецПроцедуры
 
 //Через таблицу значений
 &НаКлиенте
 Процедура СортироватьМассивЧерезТЗ(Команда)
 
 Массив = Новый Массив();
 Массив.Добавить(1);
 Массив.Добавить(2);
 Массив.Добавить(3);
 
 ОтсортированныйМассив = СортироватьМассивЧерезТЗ_Сервер(Массив);
 
 КонецПроцедуры
 
 
 &НаСервере
 Функция СортироватьМассивЧерезТЗ_Сервер(Массив)
 
 ТЗ = Новый ТаблицаЗначений;
 ТЗ.Колонки.Добавить("НаборЧисел");
 
 //Добавляем строки в ТЗ
 Для Индекс = 0 по Массив.ВГраница() Цикл
 НовСтрока = ТЗ.Добавить();
 КонецЦикла;
 
 
 ТЗ.ЗагрузитьКолонку(Массив,"НаборЧисел");//Преобразуем в таблицу значений
 ТЗ.Сортировать("НаборЧисел Убыв");//Сортируем по убыванию
 ТЗ.Сортировать("НаборЧисел Возр");//Сортируем по возрастанию
 Массив = ТЗ.ВыгрузитьКолонку("НаборЧисел");//В массив
 
 Возврат Массив;
 
 КонецФункции
 

Как свернуть массив в 1С

Пример:

&НаКлиенте
 Процедура СвернутьМассив(Команда)
 
 Массив = Новый Массив();
 Массив.Добавить("Яблоко");
 Массив.Добавить("Яблоко");
 Массив.Добавить("Банан");
 
 Соответствие = Новый Соответствие;
 Для каждого Элемент Из Массив Цикл
 Соответствие.Вставить(Элемент);
 КонецЦикла;
 
 
 Массив.Очистить();
 
 Для каждого КлючИЗначение Из Соответствие Цикл
 Массив.Добавить(КлючИЗначение.Ключ);
 КонецЦикла;
 
 КонецПроцедуры
 

Результат:

К сожалению, мы физически не можем проконсультировать бесплатно всех желающих, но наша команда будет рада оказать услуги по внедрению и обслуживанию 1С. Более подробно о наших услугах можно узнать на странице Услуги 1С или просто позвоните по телефону +7 (499) 350 29 00. Мы работаем в Москве и области.

programmist1s.ru


Смотрите также