How to get Map keys by values in Dart?

DictionaryDartKey

Dictionary Problem Overview


In Dart language how to get MAP keys by values?

I have a Map like;

{
  "01": "USD",
  "17": "GBP",
  "33": "EUR"
}

And I need to use values to get keys. How do I do that?

Dictionary Solutions


Solution 1 - Dictionary

var usdKey = curr.keys.firstWhere(
    (k) => curr[k] == 'USD', orElse: () => null);

Solution 2 - Dictionary

If you will be doing this more than a few times on the same data, you should create an inverse map so that you can perform simple key lookup instead of repeated linear searches. Here's an example of reversing a map (there may be easier ways to do this):

main() {
  var orig = {"01": "USD", "17": "GBP", "33": "EUR"};
  var reversed = Map.fromEntries(orig.entries.map((e) => MapEntry(e.value, e.key)));
  for (var kv in reversed.entries) {
    print(kv);
  }
}

Edit: yes, reversing a map can simply be:

var reversed = orig.map((k, v) => MapEntry(v, k));

Tip of the hat to Joe Conway on gitter. Thanks.

Solution 3 - Dictionary

There is another one method (similar to Günter Zöchbauer answer):

void main() {
  
  Map currencies = {
     "01": "USD",
     "17": "GBP",
     "33": "EUR"
  };
  
  MapEntry entry = currencies.entries.firstWhere((element) => element.value=='GBP', orElse: () => null);
  
  if(entry != null){
    print('key = ${entry.key}');
    print('value = ${entry.value}');
  }
  
}

In this code, you get MapEntry, which contains key and value, instead only key in a separate variable. It can be useful in some code.

Solution 4 - Dictionary

You can do the following :

var mapper = { 
              '01' : 'USD',
               '17' : 'GBP'     } 

for(var val in mapper.keys){
   
  switch(mapper[val]){
      
        case 'USD' : {
                             print('key for ${mapper[val]} is : ' '${val}');  
            }
          
          break;

        case 'GBP' : {
                             print('key for ${mapper[val]} is : ' '${val}');   
               } 
  
        }
          }

Solution 5 - Dictionary

Map map = {1: 'one', 2: 'two', 3: 'three'};

var key = map.keys.firstWhere((k) => map[k] == 'two', orElse: () => null);
print(key);

Solution 6 - Dictionary

If someone still need a solution, I wrote a simple library to deeply (search inside nested maps either) search by value inside Map. Usage is simple, because deepSearchByValue() is an extension method, so all you need to do is to import my library and call the method on your map:

import 'package:deep_collection/deep_collection.dart';


void main() {
  print({
    "01": "USD",
    "17": "GBP",
    "33": "EUR",
  }.deepSearchByValue((value) => value == 'USD'));
}

Solution 7 - Dictionary

Building on Randal Schwartz's answer:

Map<T, R> invertMap<T, R>(Map<R, T> toInvert) =>
  Map.fromEntries(toInvert.entries.map((e) => MapEntry(e.value, e.key)));

Solution 8 - Dictionary

An extension of Randal Schwartz's answer.

extension InvertMap<K, V> on Map<K, V> {
  Map<V, K> get inverse => Map.fromEntries(entries.map((e) => MapEntry(e.value, e.key)));
}

This provides us with a highly reusable solution:

var inverseMap = originalMap.inverse;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNickView Question on Stackoverflow
Solution 1 - DictionaryGünter ZöchbauerView Answer on Stackoverflow
Solution 2 - DictionaryRandal SchwartzView Answer on Stackoverflow
Solution 3 - DictionaryMakdirView Answer on Stackoverflow
Solution 4 - DictionaryPuneet NagarView Answer on Stackoverflow
Solution 5 - DictionaryFrank GueView Answer on Stackoverflow
Solution 6 - DictionaryOwczarView Answer on Stackoverflow
Solution 7 - DictionaryMatthew FalaView Answer on Stackoverflow
Solution 8 - DictionaryJaniView Answer on Stackoverflow