# Что такое список

### Что такое список

Список — это набор элементов или компонентов. Возьмем, к примеру, связку бананов. Каждый банан является элементом списка (или связки). Проще взять в руки связку бананов, чем брать бананы по одному. Точно так же работать с элементами, сгруппированными по параметрическим связям в структуре данных, проще, чем с отдельными элементами.

> Фотография предоставлена [Августусом Бину (Augustus Binu)](https://commons.wikimedia.org/wiki/File:Bananas_white_background_DS.jpg?fastcci_from=11404890\&c1=11404890\&d1=15\&s=200\&a=list).

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

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

### Индексы, отсчитываемые от нуля

Первому элементу в списке всегда назначается индекс 0, а не 1, и поначалу это может показаться странным. Поэтому запомните, что, если речь идет о первом элементе в списке, подразумевается элемент с индексом 0.

Например, если бы вам потребовалось посчитать количество пальцев на правой руке, то вы бы начали считать с 1 до 5. Однако если бы вам потребовалось внести ваши пальцы в список, то приложение Dynamo назначило бы им индексы от 0 до 4. Это может показаться странным тем, кто только начинает заниматься программированием, однако индекс, отсчитываемые от нуля, является стандартным для большинства вычислительных систем.

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

!

> a. Индекс
>
> b. Точка
>
> c. Элемент

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

Эти индексы играют ключевую роль при работе со списками.

### Входные и выходные данные

При работе со списками требуемые входные и выходные данные различаются в зависимости от используемого узла Dynamo. Для примера возьмем список из пяти точек и соединим его порт вывода с двумя разными узлами Dynamo: **PolyCurve.ByPoints** и **Circle.ByCenterPointRadius**:

\![Примеры входных данных](https://github.com/DynamoDS/DynamoPrimerNew/blob/master-rus/.gitbook/assets/what's%20a%20list%20-%20inputs%20and%20outputs.jpg)

> 1. Порт ввода *points* узла **PolyCurve.ByPoints** выполняет поиск элемента *"Point\[]"*. Этот элемент представляет собой список точек.
> 2. Выходные данные узла **PolyCurve.ByPoints** — это элемент PolyCurve, созданный на основе списка из пяти точек.
> 3. Порт ввода *centerPoint* узла **Circle.ByCenterPointRadius** запрашивает элемент *"Point"*.
> 4. Выходные данные **Circle.ByCenterPointRadius** представляют собой список из пяти окружностей, центры которых соответствуют точкам из исходного списка.

Узлы **PolyCurve.ByPoints** и **Circle.ByCenterPointRadius** используют одни и те же входные данные, однако узел **Polycurve.ByPoints** на выходе дает одну сложную кривую, а узел **Circle.ByCenterPointRadius** — пять окружностей с центрами в каждой точке. На интуитивном уровне это кажется понятным, так как сложная кривая строится путем соединения всех пяти точек, а окружности создают отдельную окружность в каждой точке. Что же происходит с данными?

При наведении указателя мыши на порт ввода *points* узла **Polycurve.ByPoints** можно увидеть, что этому порту требуется элемент *Point\[]*. Обратите внимание на скобки в конце. Этот элемент представляет список точек, и чтобы создать сложную кривую, в качестве входных данных этому узлу требуется отдельный список точек для каждой кривой. В результате узел объединяет каждый список в одну сложную кривую.

Порт ввода *centerPoint* узла **Circle.ByCenterPointRadius** запрашивает элемент *Point*. Этому узлу требуется одна точка, являющаяся отдельным элементом, для определения центра окружности. Поэтому на основе тех же входных данных мы получаем пять отдельных окружностей. Знание различий в использовании входных данных в Dynamo помогает лучше понимать, как узлы распоряжаются данными.

### Переплетение

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

Рассмотрим в качестве примера узел, который создает сегменты линий между точками (**Line.ByStartPointEndPoint**). У него есть два входных параметра, которые используются для представления координат точек:

#### Самый короткий список

Самый простой способ — попарно соединять входные данные с одинаковыми индексами, пока один из списков не закончится. Это алгоритм по самому короткому списку. Узлы Dynamo используют этот алгоритм по умолчанию.

!

#### Самый длинный список

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

!

#### Векторное произведение

Наконец, при использовании метода «Векторное произведение» создаются все возможные соединения:

!

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

!

### Что такое репликация?

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

Узлы Dynamo автоматически распознают, когда они работают со списками, и применяют эти действия к нескольким элементам. Это означает, что вам не нужно вручную перебирать элементы — все происходит автоматически. Каким образом Dynamo определяет, как обрабатывать списки, если их несколько?

Существует два основных способа.

#### Декартова репликация

Допустим, вы на кухне готовите фруктовые соки. У вас есть список фруктов — `{apple, orange, pear}` — и фиксированное количество воды для каждой порции: `1 cup`. Из каждого фрукта нужно сделать сок, используя одинаковое количество воды. В этом случае в игру вступает декартова репликация.

В Dynamo это означает, что список фруктов загружается в порт ввода фруктов узла Juice.Maker, при этом входное значение воды остается постоянным и составляет 1 стакан. Затем узел обрабатывает каждый фрукт по отдельности, смешивая его с фиксированным количеством воды. В результате получается:

`apple juice with 1 cup of water` `orange juice with 1 cup of water` `pear juice with 1 cup of water`

Для каждого фрукта добавляется одинаковое количество воды.

#### ZIP-репликация

ZIP-репликация работает немного иначе. Если бы у вас было два списка, один для фруктов (`{apple, orange, pear}`), а другой для количества сахара (`{2 tbsp, 3 tbsp, 1 tbsp}`), ZIP-репликация объединила бы соответствующие элементы из каждого списка. Далее приводится пример.

`apple juice with 2 tablespoons of sugar` `orange juice with 3 tablespoons of sugar` `pear juice with 1 tablespoon of sugar`

Каждый фрукт сопоставляется с соответствующим количеством сахара.

Подробнее о том, как это работает, см. в [руководствах по репликации и переплетению](https://github.com/DynamoDS/Dynamo/wiki/Replication-and-Replication-Guide-Part-1).

## Упражнение

> Скачайте файл примера, щелкнув указанную ниже ссылку.
>
> Полный список файлов примеров можно найти в приложении.

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

Измените настройку переплетения узла **Point.ByCoordinates** в графике выше, оставив остальные элементы без изменений.

### Самый короткий список

При выборе *Самый короткий список* в качестве варианта переплетения (также является вариантом по умолчанию) мы получаем базовую диагональную линию, состоящую из пяти точек. Пять точек — это длина наименьшего списка. Таким образом, переплетение по самому короткому списку прекращается по достижении конца этого списка.

\![Примеры входных данных](https://github.com/DynamoDS/DynamoPrimerNew/blob/master-rus/.gitbook/assets/what's%20a%20list%20-%20lacing%20exercise%2001.jpg)

### **Самый длинный список**

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

\![Примеры входных данных](https://github.com/DynamoDS/DynamoPrimerNew/blob/master-rus/.gitbook/assets/what's%20a%20list%20-%20lacing%20exercise%2002.jpg)

### **Векторное произведение**

Изменив способ переплетения на *Векторное произведение*, вы получите все возможные соединения между списками, в результате чего создается сетка 5 х 10 точек. Эта структура данных эквивалентна векторному произведению, показанному в схематическом изображении выше, однако данные теперь являются списком списков. Путем соединения сложной кривой можно увидеть, что каждый список определяется значением X, в результате чего образуется ряд вертикальных линий.

\![Примеры входных данных](https://github.com/DynamoDS/DynamoPrimerNew/blob/master-rus/.gitbook/assets/what's%20a%20list%20-%20lacing%20exercise%2003.jpg)
