Collection & Operations

Collection Types and Operations in Dart#

Dynamic Collections with Mixed Types#

How It Works#

In Dart, collections can hold elements of mixed types by using the dynamic type. This allows you to create collections where the type of each element can vary. Such collections are useful when you need flexibility in the types of elements stored but come with trade-offs like reduced type safety and potential runtime errors.

  • Dynamic Collections: Use List<dynamic> or Set<dynamic> to allow mixed types.
  • Type Safety: With dynamic, Dart does not enforce type checking at compile time, which can lead to runtime errors if the expected type is not managed properly.

How to Use#

To create a dynamic collection, specify the type as dynamic when defining the collection. You can then add elements of different types without any restrictions.

Example: Using Dynamic Collections#

void main() {
  // Creating a list with mixed types
  List<dynamic> mixedList = [1, 'Hello', true, 3.14];
  
  // Adding elements of various types
  mixedList.add([1, 2, 3]);
  
  // Printing the list
  print(mixedList); // Output: [1, Hello, true, 3.14, [1, 2, 3]]
}
  • In this example, the mixedList contains integers, strings, booleans, a double, and even another list, showcasing the flexibility of dynamic collections.

Nested Collections#

  • How It Works

Nested collections involve having one collection type inside another, such as lists of lists or maps of lists. This allows you to build more complex data structures and hierarchies, which are useful for representing multi-dimensional data or hierarchical relationships.

  • Lists of Lists: A list where each element is another list.
  • Maps of Lists: A map where each value is a list.

How to Use#

  • Define nested collections by including collections as elements within another collection. Accessing elements involves multiple levels of indexing or key lookups.

Example: Lists of Lists#

void main() {
  // Creating a list of lists
  List<List<int>> matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
  ];
  
  // Accessing elements in the nested list
  print(matrix[0][1]); // Output: 2
}

Example: Maps of Lists#

void main() {
  // Creating a map of lists
  Map<String, List<String>> groupedNames = {
    'A': ['Alice', 'Adam'],
    'B': ['Bob', 'Bella']
  };
  
  // Accessing elements in the nested map
  print(groupedNames['A']); // Output: [Alice, Adam]
}

Example: Complex Nested Collection#

void main() {
  // Creating a complex nested collection
  Map<String, List<Map<String, dynamic>>> data = {
    'users': [
      {'name': 'Alice', 'age': 30},
      {'name': 'Bob', 'age': 25}
    ],
    'admins': [
      {'name': 'Charlie', 'age': 35}
    ]
  };
  
  // Accessing elements in the nested map of lists
  print(data['users'][0]['name']); // Output: Alice
}

Conclusion#

Dynamic collections provide flexibility in handling mixed types, while nested collections enable complex data structures through hierarchies. Understanding how to work with and utilize these types of collections allows for more powerful and adaptable data management in Dart applications.