flutter - 本地图嵌套时,如何将 map 添加到 dart 中的列表?

标签 flutter dart

我有一种情况,我有一个 map ,它的值将在每次迭代时更新。我必须跟踪 map 中的变化,所以我创建了一个 List<Map<String, dynamic>>如下所示,并开始在每次迭代时将 map 添加到列表中。

令我惊讶的是,每次迭代都会添加 map ,但每次值都会更新为新值,并且没有之前 map 的记录。当我用整数而不是 map 进行相同的实验时,结果符合预期,我想知道为什么这不是 map 的情况。

请参阅下面的场景并帮助我找到将 map 添加到列表中的解决方案。

    void main() {
  int count = 0;
  List<Map<String, dynamic>> listOfMoves = [];
 
  
  Map<String, dynamic> dummyMap = {
    '0': {
      '1': "a",
      '2': 'b',
      '3': 'c',
    },
    '1': {
      '1': "d",
      '2': 'e',
      '3': 'f',
    },
    '2': {
      '1': "g",
      '2': 'h',
      '3': 'i',
    }
    };
  
  for (var i = 0; i < 5; i++) {
    //these will happen on every iterations
    count++;
    dummyMap['1'] = '$count';
    dummyMap['2'] = '$count';
    dummyMap['3'] = '$count';



 //when the map is added here to the list, the values of map should be different on every iteration. But, I see in the final map all the list has the same value that was obtained in the final iteration

    listOfMoves.add(Map.from(dummyMap));

    print(listOfMoves.toString());
  
  }
}

请检查下面文档的输出以了解更多详细信息:

https://docs.google.com/document/d/1kKyKu1bd5nT5LwiaqmJX97ModCT6UiKCbSRRFLgGS8U/edit?usp=sharing

实际输出:

[{0: {1: a, 2: b, 3: c}, 1: 1, 2: 1, 3: 1}]

[{0: {1: a, 2: b, 3: c}, 1: 2, 2: 2, 3: 2}, {0: {1: a, 2: b, 3: c}, 1: 2, 2: 2, 3: 2}]

[{0: {1: a, 2: b, 3: c}, 1: 3, 2: 3, 3: 3}, {0: {1: a, 2: b, 3: c}, 1: 3, 2: 3, 3: 3}, {0: {1: a, 2: b, 3: c}, 1: 3, 2: 3, 3: 3}]

[{0: {1: a, 2: b, 3: c}, 1: 4, 2: 4, 3: 4}, {0: {1: a, 2: b, 3: c}, 1: 4, 2: 4, 3: 4}, {0: {1: a, 2: b, 3: c}, 1: 4, 2: 4, 3: 4}, {0: {1: a, 2: b, 3: c}, 1: 4, 2: 4, 3: 4}]

[{0: {1: a, 2: b, 3: c}, 1: 5, 2: 5, 3: 5}, {0: {1: a, 2: b, 3: c}, 1: 5, 2: 5, 3: 5}, {0: {1: a, 2: b, 3: c}, 1: 5, 2: 5, 3: 5}, {0: {1: a, 2: b, 3: c}, 1: 5, 2: 5, 3: 5}, {0: {1: a, 2: b, 3: c}, 1: 5, 2: 5, 3: 5}]

预期输出:

[{0: {1: a, 2: b, 3: c}, 1: 1, 2: 1, 3: 1}]

[{0: {1: a, 2: b, 3: c}, 1: 1, 2: 1, 3: 1}, {0: {1: a, 2: b, 3: c}, 1: 2, 2: 2, 3: 2}]

[{0: {1: a, 2: b, 3: c}, 1: 1, 2: 1, 3: 1}, {0: {1: a, 2: b, 3: c}, 1: 2, 2: 2, 3: 2}, {0: {1: a, 2: b, 3: c}, 1: 3, 2: 3, 3: 3}]

[{0: {1: a, 2: b, 3: c}, 1: 1, 2: 1, 3: 1}, {0: {1: a, 2: b, 3: c}, 1: 2, 2: 2, 3: 2}, {0: {1: a, 2: b, 3: c}, 1: 3, 2: 3, 3: 3}, {0: {1: a, 2: b, 3: c}, 1: 4, 2: 4, 3: 4}]

[{0: {1: a, 2: b, 3: c}, 1: 1, 2: 1, 3: 1}, {0: {1: a, 2: b, 3: c}, 1: 2, 2: 2, 3: 2}, {0: {1: a, 2: b, 3: c}, 1: 3, 2: 3, 3: 3},{0: {1: a, 2: b, 3: c}, 1: 4, 2: 4, 3: 4}, {0: {1: a, 2: b, 3: c}, 1: 5, 2: 5, 3: 5}]

最佳答案

这是由于 dart 传递参数的方式造成的,基元(如 int、bool 和 num)是按值传递的,而对象是按值传递的 通过引用传递,see this discussion

因此,在您的代码中,您将传递 dummyMap 的引用和 count 的值:

void main() {
  int count = 0;
  List<Map<String, dynamic>> listOfMoves = [];
  List<int> countOfMoves = [];
  
  Map<String, dynamic> dummyMap = {
    '1': "one",
    '2': 'two',
    '3': 'three',
    };
  
  for (var i = 0; i < 5; i++) {
    //these will happen on every iterations
    count++;
    dummyMap['1'] = '$count';
    dummyMap['2'] = '$count';
    dummyMap['3'] = '$count';

    countOfMoves.add(count);
    listOfMoves.add(dummyMap);

    print(listOfMoves.toString());
    print(countOfMoves.toString());
  }
}

要解决此问题,您可以创建 dummyMap 的副本,通过更改此行为其提供不同的引用:

listOfMoves.add(dummyMap);

listOfMoves.add({...dummyMap});

使用文字字典和扩展运算符

或经典版本:

listOfMoves.add(Map.from(dummyMap));

然后你会得到:

[{1: 1, 2: 1, 3: 1}]
[{1: 1, 2: 1, 3: 1}, {1: 2, 2: 2, 3: 2}]
[{1: 1, 2: 1, 3: 1}, {1: 2, 2: 2, 3: 2}, {1: 3, 2: 3, 3: 3}]
[{1: 1, 2: 1, 3: 1}, {1: 2, 2: 2, 3: 2}, {1: 3, 2: 3, 3: 3}, {1: 4, 2: 4, 3: 4}]
[{1: 1, 2: 1, 3: 1}, {1: 2, 2: 2, 3: 2}, {1: 3, 2: 3, 3: 3}, {1: 4, 2: 4, 3: 4}, {1: 5, 2: 5, 3: 5}]

这个question相似但不完全相同。

关于flutter - 本地图嵌套时,如何将 map 添加到 dart 中的列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68087611/

相关文章:

ios - 使用 ShareExtension 分发 Flutter 应用程序时缺少 CFBundleShortVersionString

dart - 如何从 flutter 应用程序中删除 native 启动画面?

syntax - Dart中点前的问号

Dart httpServer 404 未找到页面

flutter - 如何在提交时将文本字段更改为另一个小部件?

flutter - 如何更改父小部件内所有子小部件的文本?

azure - Flutter Azure Face API

flutter - 如何在状态栏后面绘制 ListView 而无需填充?

flutter - 如何在Flutter中通过BloC模式在页面的加载(初始)中设置两个不同的列表

dart - 如何将 FutureBuilder<File> 转换为 BoxDecoraiton Image