Dart:将Map转换为对象列表

74

我进行了几次谷歌搜索,没有发现任何有用的内容。在尝试做一些本该相当简单的事情时,一直遇到一些错误。将类似于{2019-07-26 15:08:42.889861: 150, 2019-07-27 10:26:28.909330: 182}这样的映射转换为以下对象格式的列表:

class Weight {
  final DateTime date;
  final double weight;
  bool selected = false;

  Weight(this.date, this.weight);
}

我尝试了这样的方法:List<Weight> weightData = weights.map((key, value) => Weight(key, value));

显然,对于maps没有toList()方法。到目前为止,我不是很喜欢在Dart中使用maps。对象类型“map”和“map”函数之间的术语混淆使得在互联网上进行故障排除非常痛苦。


14
Map有一些有用的getter方法,如keysvalues,你可以在它们上面调用toList()方法,具体取决于你想要获取键还是值。此外,还有一个entries方法可以让你这样做:weights.entries.map<SomeVClass>(someFunction).toList() - Richard Heap
2
这个问题是真实存在的 :) => 对象类型映射和映射函数之间的命名方式令人困惑。 - Asad S
12个回答

153

继Richard Heap上面的评论之后,我会:

List<Weight> weightData =
  mapData.entries.map( (entry) => Weight(entry.key, entry.value)).toList();

不要忘记调用 toList,因为 Dart 的 map 返回一种 Iterable 类型。


3
如果重量有多个字段会发生什么? - EngineSense
@EngineSense 那么你的entry值本身也会包含一个对象,是吗?然后你可以使用entry.object.att1,entry.object.att2等来使用地图中的正确数据来实例化你的新Weight对象。 - dingo

18
List<Weight> weightData = List();

weights.forEach((k,v) => weightData.add(Weight(k,v))); 

3
对于任何映射的调用条目,它会给你一个MapEntry列表:weights.entries.map((e) => Weight(e.key,e.value)).toList()。其中,Weight是根据键和值创建的对象。 - Adel Ben Hamadi
1
Op只是想要一个对象列表。 - Pushan Gupta

11

有时类型转换会失败,您可以通过执行以下操作强制进行转换:

List<Weight> weightData =
  weightData.entries.map<Weight>( (entry) => Weight(entry.key, entry.value)).toList();

我的项目中有一个例子,如果没有类型转换就无法正常工作:

List<NetworkOption> networkOptions = response.data['data']['networks']
          .map<NetworkOption>((x) => NetworkOption.fromJson(x))
          .toList();

7

使用map对象上的entries属性。

这将返回一个类型为MapEntry<key,value>List

myMap.entries.map((entry) => "${entry.key} + ${entry.value}").toList();

6
你也可以使用 for 集合来达到相同的效果。
var list = [for (var e in map.entries) FooClass(e.key, e.value)];

5

细节

  • Flutter 1.26.0-18.0.pre.106

解决方案

/libs/extensions/map.dart

extension ListFromMap<Key, Element> on Map<Key, Element> {
  List<T> toList<T>(
          T Function(MapEntry<Key, Element> entry) getElement) =>
      entries.map(getElement).toList();
}

使用方法

import 'package:myApp/libs/extensions/map.dart';

final map = {'a': 1, 'b': 2};
print(map.toList((e) => e.value));
print(map.toList((e) => e.key));

3
如果您需要将Map的值转换为列表,最简单的一行代码如下:
final list = map.values.toList(); 

2
请记住,Stack Overflow 不仅旨在解决当前的问题,还要帮助未来的读者找到类似问题的解决方案,这需要理解底层代码。对于我们社区中的初学者和不熟悉语法的成员来说,这尤其重要。鉴于此,您能否编辑您的答案,包括您正在做什么以及为什么您认为这是最好的方法的解释? - Tyler2P
2
抱歉,但有时候简单的代码比解释更能说明问题。 - Maksim Gridin
1
@Tyler2P 我觉得toList()相当容易理解 - Ojonugwa Jude Ochalifu

2
你可以这样做:
List<Weight> weightData = (weights as List ?? []).map((key, value) => Weight(key,value)).toList()

或者你可以尝试:

List<Weight> weightData = List.from(weights.map((key, value) => Weight(key, value)))

1
维多尔的答案是正确的。无论如何,这对我起作用了。
      List<String> list = new List();
  userDetails.forEach((k, v) => list.add(userDetails[k].toString()));

1

非常简单,只需像这样初始化一个自定义对象列表

List<CustomObject> list=[];
    for (int i = 0; i < map.length; i++) {
      CustomObject customObject= CustomObject(
       date:map[i]['key'],
       weight:map[i]['key']
      );
      list.add(CustomObject);
    }

希望它对你有用,谢谢。

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