Работа с List и Map | DART

Handling Lists and Maps
Handling Lists and Maps

Привет, если вы на пути изучения Flutter/Dart или вам просто интересно почитать про разработку подписывайтесь на мой канал в telegram, буду рад вас видеть! А я сегодня поговорим про функции в DART-е!

В этой главе изложены основы обработки данных с помощью Dart. Цель этой главы - рассмотреть Lists (списки) и Maps (карты), которые используются для предоставления базовых структур данных для обработки информации в Dart.

Если вам посчастливилось быть знакомым с другими языками, то многие из представленных концепций должны быть вам знакомы. Однако, если вы впервые сталкиваетесь с этими методами, примеры фрагментов кода являются самодостаточными. Возможно, вам будет полезно поработать с примерами и поэкспериментировать с ними, чтобы получить представление о работе языка. Глава начинается с обсуждения списков, которые являются индексируемыми структурами данных, используемыми для хранения объектов. Списки - очень распространенные элементы в Dart, поскольку их можно использовать в различных сценариях.

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

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

Создание списков данных

Проблема

Вам нужен способ использовать список значений в приложении Dart.

Решение

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

Вот пример того, как использовать список в Dart:

void main() { List listMonths = ['January', 'February', 'March']; listMonths.forEach(print); }

Обсуждение

Списки очень универсальны и могут использоваться в самых разных обстоятельствах. В предыдущем примере List используется для хранения месяцев года, как показано на рисунке 4-1.

Рисунок 4.1 структура данных list
Рисунок 4.1 структура данных list

Обсуждение

List используется для хранения строки, но на самом деле оно может содержать множество типов данных, что делает этот объект чрезвычайно гибким. Класс List предоставляет ряд полезных методов, таких как forEach, length, reverse, isEmpty и isNotEmpty. К каждому элементу в списке можно обращаться напрямую, а также к нему можно получить доступ с помощью метода forEach.

Список обозначается с помощью квадратных начальных и конечных скобок. В квадратных скобках указаны элементы списка, разделенные запятыми. Элементы списка могут быть инициализированы при объявлении или изменены позже в процессе обработки.

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

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

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

Внесение изменений в список данных

Проблема

Вы хотите добавить новый контент в существующий список.

Решение

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

Вот пример того, как добавить элемент списка в Dart:

void main() { List listMonths = ['January', 'February', 'March']; listMonths.add('April'); listMonths.forEach(print); }

Обсуждение

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

Когда вы добавляете новый элемент, как показано на рисунке 4-2, класс List выполняет всю связанную с ним обработку. Метод add знает, как добавить переданную информацию, и обеспечит обновление соответствующих свойств класса (например, длины). Таким образом, в примере вы увидите выходные данные месяцев как “Январь”, “Февраль”, “Март”, “Апрель”. Вы также увидите, что длина списка изменена, чтобы отразить добавление четвертого элемента.

Рисунок 4-2. Добавление элемента в список
Рисунок 4-2. Добавление элемента в список

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

Использование списков со сложными типами

Проблема

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

Решение

Используйте списки для организации объединения других типов данных. Списки могут быть особенно полезны для обработки других структур данных, таких как Maps (см. рецепт 4.4).

Вот пример того, как использовать список со сложными типами данных в Dart:

void main() { Map<String, dynamic> filmStarWars = {"title": "Star Wars", "year": 1977}; Map<String, dynamic> filmEmpire = {"title": "The Empire Strikes Back", "year": 1980}; Map<String, dynamic> filmJedi = {"title": "The Return of the Jedi", "year": 1983}; List listFilms = [filmStarWars, filmEmpire, filmJedi]; Map<String, dynamic> currentFilm = listFilms[0]; print(currentFilm); print(currentFilm['title']); }

Обсуждение

В примере данные о фильме добавляются в Map, содержащей информацию о названии и годе, как показано на рисунке 4-3. Здесь мы используем список для управления отдельными Maps, чтобы можно было комбинировать отдельные элементы. Результирующий список обеспечивает удобную структуру данных для доступа к информации, подлежащей хранению.

Рисунок 4-3. Список с сложным типом данных
Рисунок 4-3. Список с сложным типом данных

Доступ к информации внутри списка осуществляется по тому же процессу, что и к обычному списку. Чтобы получить доступ к информации, вам необходимо разыменовать переменную. В этом контексте для разыменования используйте индекс, чтобы сообщить Dart, что вы хотите получить доступ к значению свойства listFilms[0] означает доступ к первому элементу в списке.

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

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

Обработка Map сопоставлений Ключ/Значение

Проблема

Вы хотите обработать пару ключ/значение в приложении Dart.

Решение

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

Вот пример того, как объявить карту в Dart:

void main() { Map<int, String> mapMonths = {0: 'January', 1: 'February', 2: 'March'}; Map<int, String> moreMonths = {3: 'April', 4: 'May'}; mapMonths.addEntries(moreMonths.entries); mapMonths.forEach((key, value){ print('$key: $value'); }); }

Обсуждение

В примере кода карта используется для определения набора данных на основе информации о месяце. Конструкция этого типа очень полезна для объединения фрагментов информации, которые выигрывают от сочетания ключ/значение, как показано на рисунке 4-4.

Рисунок 4.4. Структура данных Map
Рисунок 4.4. Структура данных Map

Структура карты месяца устанавливает связь между ключом и значением, например, месяц 0 - январь, а январь - месяц 0. Структура карты очень полезна с точки зрения обработки информации о списке, такой как объектная запись JavaScript (JSON).

Объявление Map соответствует стандартному формату переменной. Примечание: Map на самом деле является вызовом функции, поэтому для этого требуется добавление фигурных скобок. В нашем примере мы указываем, что карта будет состоять из целого числа и строки, что означает, что в качестве ключа (т.е. индекса) используется число. Поле string value содержит ссылку на месяц. Вы также могли бы определить значение как динамическое, что позволило бы использовать различные типы переменных, обеспечивая дополнительную гибкость. Чтобы быть более конкретным, вы могли бы ввести динамическое определение для явной замены строки. Если вы внесете это изменение, Dart автоматически определит правильный тип данных на основе присвоения переменной.

Чтобы заполнить карту, определите ключ (например, mapMonth), а затем присвойте значение (например, январь). Присвоение значений может производиться в любом порядке; важно соблюдать осторожность, чтобы не дублировать используемые ключи. Для добавления элемента на карту требуются как ключ, так и значение. В примере создается дополнительная структура карты с именем aprilMonth. Добавьте новый месяц в существующую структуру, вызвав метод addEntries с параметром new Month Map.

Чтобы получить доступ к информации в классе Map, используйте методы и свойства Map. Карта имеет ряд доступных методов, которые можно использовать для доступа к связанным элементам данных. Чтобы выполнить цикл по каждому элементу, используйте ключ для доступа к отдельным элементам. В примере используется метод Map forEach для доступа к каждому элементу структуры данных. При доступе к ключу информация, связанная с картой, может быть получена путем объединения этих элементов вместе.

Что касается доступа к данным, всегда стоит проверять информацию руководства по стилю, предоставленную командой Dart. В этом случае вместо использования forEach вы также можете использовать цикл for. Руководство, связанное с доступом, определено в документации Dart.

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

Вывод содержимого структуры данных Map

Проблема

Вы хотите вывести значение переменной картографических данных.

Решение

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

Вот пример получения свойства Map и вывода значения с помощью Dart:

void main() { Map<int, String> mapMonths = {0: 'January', 1: 'February', 2: 'March'}; print ("Month: ${mapMonths[0]}"); print ("Map: $mapMonths"); }

Обсуждение

В примере кода доступ к значению в структуре карты осуществляется через его целочисленный ключ. Когда требуется значение, мы предоставляем ключ для индексации карты и извлечения желаемого значения. Первая инструкция print явно запрашивает информацию, связанную с ключом [0]. Использование фигурных скобок вокруг переменной необходимо для обеспечения вывода значения месяца. Во втором операторе печати мы выводим всю карту для переменной mapMonths.

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

Проверка наличия содержимого в Map

Проблема

Вы хотите подтвердить, что ключ существует в Map.

Решение

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

Вот пример проверки наличия ключа в Map с помощью Dart:

void main() { Map<int, String> mapMonths = {0: 'January', 1: 'February', 2: 'March'}; if (mapMonths[0]!=null) { print ('Test 1: Key exists'); } if (mapMonths.containsKey(2)) { print('Test 2: Key exists'); } }

Обсуждение

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

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

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

Вывод сложных типов данных

Проблема

Вы хотите вывести переменную, основанную на сложном типе данных.

Решение

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

Вот пример того, как напечатать сложный тип данных:

import 'dart:convert'; void main() { // Create JSON value Map<String, dynamic> data = { jsonEncode('title'): json.encode('Star Wars'), jsonEncode('year'): json.encode(1977) }; // Decode the JSON Map<String, dynamic> items = json.decode(data.toString()); print(items); print(items['title']); print("This is the title: $items['title']"); print('This is the title: ${items['title']}'); }

Обсуждение

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

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

// В первом варианте используется интерполяция строк без фигурных скобок: print("This is the title: $items['title']"); // Во втором случае использования используется интерполяция строк с помощью фигурных скобок: print('This is the title: ${items['title']}');

Предыдущие инструкции выглядят эквивалентными, но это не так. В первой инструкции print Dart интерпретирует переменную, которая будет отображаться как элементы. Чтобы правильно отобразить переменную, на самом деле требуется, чтобы она была заключена в фигурные скобки, согласно второй строке. Выполнение этого гарантирует, что значение, связанное с элементами['title'], будет правильно интерпретировано инструкцией print.

1 комментарий

"Класс List предоставляет ряд полезных методов, таких как forEach, length, reverse, isEmpty и isNotEmpty."
Из методов здесь только forEach. Остальное - свойства (properties).

1
Ответить