Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter dart Map with multiple keys for very same value

Is there any kind of collection to declare a map with multiple keys linked to the very same value ?

I want the map to be initialized at the same time that it is declared. Ideally something like:

MyMap<String, String> mymap = {['red', 'blue', 'green'] : 'Rock', ['pink', 'yellow' ...etc}

So far I found Multimap in the documentation but it seems that its one key for multiple value, and on top of that I have a lot of trouble for implementing since that despite the documentation there is 0 example given.

Here my try so far:

static Iterable mylist = ['red', 'blue', 'green']; // I want to associate these strings to 'Rock'
static Iterable mylist = ['pink', 'yellow', 'cyan']; // I want to associate these strings to 'Funk'
static Multimap<String,String> okayboomer = Multimap.fromIterable(mylist);//, {K key(dynamic element), V value(dynamic element)});

And then whenever I access okayboomer['red'] I would get 'Rock'.

I was also thinking about HashMap

Any help strongly appreciated!

like image 611
Antonin GAVREL Avatar asked Nov 07 '22 06:11

Antonin GAVREL


1 Answers

You don't necessarily need any special data structure; a normal Map can have multiple keys for the same value, and you just need a helper function to make initializing it more convenient:

Map<String, String> makeMyMap(Map<List<String>, String> map) {
  var newMap = <String, String>{};
  for (var entry in map.entries) {
    var keyList = entry.key;
    for (var key in keyList) {
      newMap[key] = entry.value;
    }
  }
  return newMap;
}

and then you should be able to do:

var mymap = makeMyMap({
  ['red', 'blue', 'green'] : 'Rock',
  ['pink', 'yellow', 'cyan']: 'Funk',
});

Note that the above Map would work for lookups, and if you mutated values in the map, the related keys would still refer to the same object. If, however, you need to replace values in the map, related keys would continue referring to the old object. If you need to do that, you would need to add a level of indirection around the values. For example:

class Wrapped<T> {
  Wrapped(this.value);
  T value;
}

var map = <String, Wrapped<String>>{};
map['red'] = map['blue'] = map['green'] = Wrapped('Rock');
map['red'].value = 'Funk';
print(map['blue'].value); // Prints: Funk

You could derive a class from DelegatingMap to automatically unwrap values when using operator [] and to automatically update existing Wrapped objects for operator []=.

like image 174
jamesdlin Avatar answered Nov 15 '22 06:11

jamesdlin