Flutter如何迭代List并访问索引

4

我尝试过其他解决方案,如使用asMap()forEach,但是一直出现不同的错误。例如,它会说我的ChartBar的返回类型不是“MapEntry”,由匿名闭包定义,或者此处的表达式为'void'类型,因此无法使用。

Row(
    mainAxisSize: MainAxisSize.min,
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    crossAxisAlignment: CrossAxisAlignment.end,
    children: myList.map((data) {
      return ChartBar(
          ///etc
    }).toList(),
  )

我也需要 index


@mirkancal 这就是我所提到的问题,那些解决方案给了我上述描述的错误。 - Hasen
你可以尝试使用myList.asMap().map((MapEntry data) => data.value).toList()吗? - mirkancal
如问题所述,我遇到了错误“ChartBar不是'MapEntry'”。 - Hasen
ChartBar是什么?是你自己的小部件吗? - Fernando Rocha
@jamesdlin 你想让我尝试什么确切的代码?他的代码甚至不包括小部件。 - Hasen
显示剩余6条评论
2个回答

9
mirkancal的建议不起作用,因为Map.map返回另一个Map(因此您传递给它的枚举回调函数应返回MapEntry)。
相反,您需要使用Map.entries,以便您可以使用Iterable.map来构造List
Row(
    mainAxisSize: MainAxisSize.min,
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    crossAxisAlignment: CrossAxisAlignment.end,
    children: myList.asMap().entries.map((MapEntry entry) {
      return ChartBar(entry.key, entry.value);
    }),
  )

你也可以使用Dart的新集合-for结构:

Row(
    mainAxisSize: MainAxisSize.min,
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    crossAxisAlignment: CrossAxisAlignment.end,
    children: [for (MapEntry entry in myList.asMap().entries)
      ChartBar(entry.key, entry.value)
    ],
  )

在上述代码中,entry.key 将会是索引,而 entry.value 则是在 myList 中的原始值。

使用不同的列表时,我会收到错误消息:“在'for'循环中使用的类型'Map<int,String>'必须实现Iterable。”或“在'for'循环中使用的类型'Map<int,double>'必须实现Iterable。” - Hasen
@Hasen 抱歉,我忘记添加 .entries 了。我已经更新了我的答案。 - jamesdlin
这对我来说是一种奇怪的代码,为什么它全部都包含在方括号中? - Hasen
@Hasen 我已经更新了我的答案,并提供了更好的解释。 - jamesdlin
请查看以下答案 https://dev59.com/QVQI5IYBdhLWcg3w9Agm#59447850 和 https://dev59.com/-FQI5IYBdhLWcg3w7QHJ#68357576。 - Michael Ekoka
显示剩余3条评论

-1

对于索引,您可以使用列表中的indexOf(value)函数来获取索引值。例如:

List list = List.generate(3, (int index) => index * index); // [0, 1, 4]

list.indexOf(4) // returns 2

关于您的另一个问题,我需要看更多的代码来了解您如何填充myList。如果适用的话,我建议采用以下方法来呈现您的Row子元素。使用一个函数来返回该列表,例如:
buildList() {
 List<Widget> list = List<Widget>();

 chartBars.forEach((chart) => { //chartBars list with info
  // add your ChartBar widget to the list with appropiate info
  list.add(ChartBar(someProperty: chart.property));
 });
 return list;
}

然后在您的Row小部件上,只需在构建其子元素时调用该函数:

Row(
    mainAxisSize: MainAxisSize.min,
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    crossAxisAlignment: CrossAxisAlignment.end,
    children: buildList()      
)

将小部件拆分为方法是一种反模式。https://iirokrankka.com/2018/12/11/splitting-widgets-to-methods-performance-antipattern/ - mirkancal
有没有更简单的方法来做这件事?难道没有简单的调整现有代码来显示索引吗? - Hasen
@mirkancal 感谢你提醒,我对Flutter还比较新,可能不了解最佳实践。@Hasen 你尝试使用 myList.indexOf(data) 来显示索引了吗? - Rodolfo Franco
1
使用 indexOf() 会相当低效,将本应是 O(n) 操作变成了 O(n^2)。 - jamesdlin
@mirkancal 是的,indexOf()可以工作,但似乎不是最优雅的方法。 - Hasen
如果列表中有重复项,这将无法正常工作。 - tmath

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