如何在Dart中通过值获取Map键?

70
在Dart语言中,如何通过值获取MAP键?
我有一个Map,例如:
{
  "01": "USD",
  "17": "GBP",
  "33": "EUR"
}

我需要使用值来获取键。我该如何做到这一点?

8个回答

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

谢谢Günter,它正在工作...顺便问一下,我在哪里可以获取有关此信息的详细信息?这样我就可以学习理解并在我的高级地图项目中使用了。 - Nick
3
我认为这个东西本身并没有被记录下来。有Mapkeys属性和IterablefirstWhere方法,其余的是将它们有意义地结合在一起使用。https://api.dartlang.org/stable/2.0.0/dart-core/Map/keys.html,https://api.dartlang.org/stable/2.0.0/dart-core/Iterable/firstWhere.html - Günter Zöchbauer
4
@zoechi竞选总统 - 最白目
由于某些原因,无法获取键值! - EngineSense

23

如果您将在同一数据上执行此操作多次,则应创建反向映射,以便可以执行简单的键查找而不是重复的线性搜索。以下是反转映射的示例(可能有更简单的方法):

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);
  }
}

编辑:是的,反转一个映射可以简单地进行以下操作:

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

向Gitter上的Joe Conway致以敬意。感谢。


9

还有一种方法(类似于Günter Zöchbauer的回答):

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}');
  }

}

在这段代码中,你会得到一个MapEntry,其中包含了键和值,而不是仅将键存在一个单独的变量中。这在某些代码中可能非常有用。

这很有用,因为(元素)包含键和值,并且在测试条件中帮助了我处理键和值,因为我具有相同的值但不同的键,但我需要两个条目。由于“firstWhere”忽略了重复项。谢谢。 - Ant D
1
很高兴我的答案对你有帮助。MapEntry确实有助于可视化数据结构,这对于调试和测试非常有用。 - Makdir
谢谢!对我有用!这个答案应该有更多的赞! - Al Mamun

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

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

虽然这段代码可能有助于解决问题,但最好包含一些上下文,解释它的工作原理以及何时使用它。仅提供代码的答案在长期内往往不太有用。请参阅如何编写一个好的答案?获取更多信息。 - Klaus Gütter
在我的情况下,这个方法可行:map.entries.firstWhere((element) => element.value == 'two', orElse: () => null).key; - SardorbekR

3
如果有人仍然需要解决方案,我写了一个简单的库 deep_collection 来深度搜索(包括在嵌套的 map 中搜索)Map 内的值。使用方法很简单,因为 deepSearchByValue() 是一个扩展方法,所以你所需要做的就是导入我的库并在你的 map 上调用该方法:
import 'package:deep_collection/deep_collection.dart';


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


2
您可以做如下操作:
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}');   
               } 

        }
          }

1
不够有效和可重用。您在switch中硬编码值,这使得维护和重构变得困难。 - Michał Dobi Dobrzański

1
Randal Schwartz的回答的一个扩展。
extension InvertMap<K, V> on Map<K, V> {
  Map<V, K> get inverse => Map.fromEntries(entries.map((e) => MapEntry(e.value, e.key)));
}

这为我们提供了一个高度可重用的解决方案:
var inverseMap = originalMap.inverse;

1
在 Randal Schwartz 的回答基础上构建:
Map<T, R> invertMap<T, R>(Map<R, T> toInvert) =>
  Map.fromEntries(toInvert.entries.map((e) => MapEntry(e.value, e.key)));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接