-1

I want to store in a variable, the path to an element in a Map for quicker access later on

class Student{
 String name;
 int age;
 Icon icon;
 Color color;
 Student(this.name, this.age, this.icon, this.color);
}

Student student_1 = Student('James', 14, Icon(Icons.label),Colors.green);
Student student_2 = Student('Andy', 12, Icon(Icons.label),Colors.blue);
Student student_3 = Student('Peter', 13, Icon(Icons.label),Colors.green);
Student student_4 = Student('Cathy', 15, Icon(Icons.label),Colors.pink);
Student student_5 = Student('Pamela', 14, Icon(Icons.label),Colors.amber);

Map<Student,dynamic> mapStudent = {student_1 : [student_2 , {student_3 : [student_4 , student_5, 
 student_2]}]};

var tmp = mapStudent[student_1][1][student_3][0];

The path I want to store is[student_1][1][student_3] so I can later access the details in that element without having to go through a loop. Is it possible?

I came across a Class called PathMap class but don't know how to use it or whether it is meant for what I'm trying to achieve. PathMap class

Ant D
  • 2,481
  • 6
  • 18
  • 34
  • 1
    Why are you nesting the map like this? – SnowmanXL Jun 28 '21 at 12:40
  • It is an example of a hierarchy I am trying to work with. – Ant D Jun 28 '21 at 12:48
  • I'm not sure I understand your question. Can't you save ```var tmp = mapStudent[student_1][1][student_3]``` and then access the desired elements with only ```tmp[0]```, ```tmp[1]``` and so on? What do you mean by ```store a path``` ? – Naslausky Jun 28 '21 at 14:00
  • Now I too am a bit confused about my approach. What I wanted was to be able to get the Parent of any level in the map. – Ant D Jun 28 '21 at 14:41

1 Answers1

1

I had a simmilar use case recently in which I had a List of items which belonged to a hierarchy for example:

  factory Comment(
      {required int id,
        required String content,
        required DateTime inserted,
        CommentAuthor? commentAuthor,
        int? parentId})/// This is the most important attribute `parentId`

Comments could be nested via its parentId just like Student in your map implementation. I saw that hierarchy could be more correctly represented using trees so I created a slimmed down tree data structure like this one:

/// Simple N-ary tree data structure
class Node<T> {
  final T value;
  final List<Node<T>> children;

  Node(this.value, {List<Node<T>>? children}) : children = children ?? [];

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Node &&
          runtimeType == other.runtimeType &&
          value == other.value &&
          DeepCollectionEquality().equals(other.children, children);

  @override
  int get hashCode => value.hashCode ^ children.hashCode;

  bool get isLeaf => children.isEmpty;
}

With this tree implementation now you have a safe, strongly typed hierarchy.

Extra : Transform list into tree (adapted from here)

/// Sample usage :
/// ```
/// List<Node<Comment>> commentListToTree(List<Comment> comments) {
///   return listToTree<Comment, int>(
///     comments,
///     idSelector: (c) => c.id,
///     parentIdSelector: (c) => c.parentId,
///     rootId: null,
///  );
/// }
/// ```
///

List<Node<T>> listToTree<T, IdType>(
  List<T> list, {
  required IdType? Function(T) idSelector,
  required IdType? Function(T) parentIdSelector,
  required IdType? rootId,
}) {
  if (list.isEmpty) return [];
  final tree = <Node<T>>[];
  for (final item in list.where((e) => parentIdSelector(e) == rootId)) {
    tree.add(Node<T>(
         item,
        children: listToTree(
          list,
          idSelector: idSelector,
          parentIdSelector: parentIdSelector,
          rootId: idSelector(item),
        )));
  }
  return tree;
}
croxx5f
  • 5,163
  • 2
  • 15
  • 36
  • Thank you for your helpful answer. Also when the tree gets generated, is it possible to add all the parent Ids of that particular node, as a list member of that node? In the Sample usage shown the 'rootId: null' gives empty list, using int 0 gives the result. – Ant D Jun 29 '21 at 14:23