【问题标题】:Get iteration index from List.map()从 List.map() 获取迭代索引
【发布时间】:2019-07-26 04:57:39
【问题描述】:

我在字母列表上编写了一个迭代,并使用“地图”类将卡片放在屏幕上。

在代码中你可以看到我做了一行,并使用“地图”将卡片上的所有用户板打印到屏幕上。我想在里面添加一些逻辑,所以我需要获取元素的 id(用于录制事件)。 有没有办法让我做到这一点?

实际上,我想在 userBoard 上获取元素的特定索引。

代码:

Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: <Widget>[
            Row(
              children: userBoard
                  .map((element) => Stack(children: <Widget>[
                        Align(
                          alignment: Alignment(0, -0.6),
                          child: GestureDetector(
                            onTap: (() {
                              setState(() {
                                // print("element=${element.toString()}");
                                // print("element=${userBoard[element]}");
                              });
                            }),
                            child: SizedBox(
                              width: 40,
                              height: 60,
                              child: Card(
                                  shape: RoundedRectangleBorder(
                                    borderRadius: BorderRadius.circular(5.0),
                                  ),
                                  child: Center(
                                    child: Text(element,
                                        style: TextStyle(fontSize: 30)),
                                  )),
                            ),
                          ),
                        )
                      ]))
                  .toList(),
            )
          ],
        ),
}

Picture - each card is "element" of the map. I want to get the indexes for the function onTap.

【问题讨论】:

    标签: loops dictionary indexing dart flutter


    【解决方案1】:

    要访问索引,您需要使用asMap 运算符将列表转换为地图。

    示例

    final fruitList = ['apple', 'orange', 'mango'];
    final fruitMap = fruitList.asMap(); // {0: 'apple', 1: 'orange', 2: 'mango'}
    
    // To access 'orange' use the index 1.
    final myFruit = fruitMap[1] // 'orange'
    
    // To convert back to list
    final fruitListAgain = fruitMap.values.toList();
    

    您的代码

    userBoard.asMap().map((i, element) => MapEntry(i, Stack(
      GestureDetector(onTap: () {
        setState(() {
          // print("element=${element.toString()}");
          // print("element=${userBoard[i].toString()}");
        });
      }),
    ))).values.toList();
    

    【讨论】:

      【解决方案2】:

      当列表没有重复元素时,可以获取索引使用list.indexOf

      例子

      userBoard.map((element) {
        // get index
        var index = userBoard.indexOf(element);
        return Container(
      
        );
      }).toList()
      

      【讨论】:

      • 当你的列表中的重复元素返回第一个创建项目的索引时会出错。
      • 这样效率很低。
      • 必须检查重复的元素
      • @jamesdlin 为什么效率低?
      • @SimpleUXApps 因为list.indexOf 必须遍历列表才能找到指定的元素。每个list.indexOf 调用都是 O(n),因此将它用于列表的每个元素将是 O(n^2)。这是低效的,因为这个操作很容易在 O(n) 时间内完成。
      【解决方案3】:

      如果你想迭代,最简单的方法

      我们可以用一个新函数扩展Iterable

      import 'dart:core';
      
      extension IndexedIterable<E> on Iterable<E> {
        Iterable<T> mapIndexed<T>(T Function(E e, int i) f) {
          var i = 0;
          return map((e) => f(e, i++));
        }
      }
      

      用法:

      myList.mapIndexed((element, index) {});
      

      取自here

      【讨论】:

        【解决方案4】:

        使用List.generate的另一种方法:

        var list = ['y', 'e', 's'];
        var widgets = List.generate(list.length, (i) => Text(list[i]));
        

        【讨论】:

        • 这是最好的答案
        【解决方案5】:

        Dart 已经发布了 collection 包,该包带有 mapIndexed 对所有 Iterables 的扩展。

        import 'package:collection/collection.dart';
        
        void main() {
          final fruitList = ['apple', 'orange', 'mango'];
          final withIndices = fruitList.mapIndexed((index, fruit) => "$index - $fruit");
          print(withIndices);
        }
        

        (DartPad)

        该软件包附带各种方便的扩展和有用的工具来处理集合。

        【讨论】:

          【解决方案6】:

          您可以简单地使用mapIndexed 方法:

          userBoard.mapIndexed(
            (int index, element) => Container( ... ))
               .toList();
          

          这是 FIC 包的众多扩展之一:https://pub.dev/packages/fast_immutable_collections


          如果您不想将包添加到项目中,您可以复制扩展本身:

          extension FicListExtension<T> on List<T> {
          
            /// Maps each element of the list.
            /// The [map] function gets both the original [item] and its [index].
            Iterable<E> mapIndexed<E>(E Function(int index, T item) map) sync* {
              for (var index = 0; index < length; index++) {
                yield map(index, this[index]);
              }
            }
          }
          

          注意:我是该软件包的作者之一。


          更新:我现在从FIC package 中删除了一些方法,例如Iterable.mapIndexed(),因为Google 在他们的collection package 中添加了类似的方法,并且我希望这两个包兼容.

          【讨论】:

            【解决方案7】:

            你可以试试这个

            children: [
                      for(int index = 0; index < list.length; index++)
                        Text(list[index])
                    ]
            

            【讨论】:

              【解决方案8】:

              你可以使用list.asMap()

              var result = list.asMap().map((e) => '${e[0]} - ${e[1]});
              print(result);
              

              https://api.dartlang.org/stable/2.2.0/dart-core/List/asMap.html

              【讨论】:

              • 我想发送一个“userBoard”索引作为参数 userBoard.map((element) => Container( child: Text(element) //....一些代码和按钮监听器函数(元素索引);
              【解决方案9】:

              您可以使用 asMap() 和 entries.map() 来获取索引。

              list.asMap().entries.map((e) {
                    var index = e.key;
                    var value = e.value;
                    // ...
                  }
              

              【讨论】:

                【解决方案10】:

                没有获取迭代索引的内置函数。

                您可能想要的是map,它会为您提供索引:

                children: enumerate(
                  list,
                  (index, item) => Text("event_$index")
                ).toList();
                

                enumerate的实现很简单:

                Iterable<E> enumerate<E, T>(
                    Iterable<T> items, E Function(int index, T item) f) {
                  var index = 0;
                  return items.map((item) {
                    final result = f(index, item);
                    index = index + 1;
                    return result;
                  });
                }
                

                【讨论】:

                  【解决方案11】:

                  另一个解决方案是让你的对象的 hascode 是唯一的 int 示例:

                  yourClass.hasCode()
                  

                  这将为每次迭代返回一个类似 123456789 的 id

                  您在需要时在其他小部件中使用时

                  onSelectChanged: (d) {
                      setState(() {
                         selectedRow = d == true ? object.hascode : null;
                      });
                   },
                   selected: object.hascode == selectedRow,
                  

                  【讨论】:

                    【解决方案12】:

                    也可以试试这个:

                    list.asMap().keys.toList().map((index) {
                      // var item = list[index];
                      // index is the index of each element.
                      return youFunction(index);
                    });
                    

                    我还在我的博客中写了其他方法。 https://medium.com/@channaly/map-with-index-in-dart-flutter-6e6665850ea8

                    【讨论】:

                      【解决方案13】:

                      你可以先使用package:quiver's enumerate function

                      enumerate(userBoard).map((indexedValue) {
                        final index = indexedValue.index;
                        final element = indexedValue.value;
                        // ...
                      })
                      

                      【讨论】:

                        【解决方案14】:

                        使用map 将您的列表转换为另一个列表。

                        var yourList = ['A', 'B', 'C'];
                        var textList = yourList.map((e) => Text(e)).toList();
                        

                        用法:

                        Column(
                          children: textList,
                        )
                        

                        【讨论】:

                        • 索引在哪里?
                        • @NearHuscarl 这可能无法直接回答标题中的问题。
                        【解决方案15】:

                        它在飞镖中非常简单直接。

                        myList.map((item) =>
                        print(myList.indexOf(item));//here I printing index             
                        ).toList()
                        

                        【讨论】:

                        • 这是低效的。默认实现遍历列表以找到给定的项目,因此在最坏的情况下你有 O(n²) (如果我没有完全关闭)。这也是不准确的。给定final myList = [0, 1, 2, 1];,这将打印0, 1, 2, 1 而不是0, 1, 2, 3
                        【解决方案16】:

                        当前版本的内置collection package现在包含方法mapIndexed和其他List/Iterableextension methods的综合集合。

                        import 'package:collection/collection.dart';
                        

                        【讨论】:

                          【解决方案17】:
                          Map map = {
                          '1st':'first',
                          '2nd':'second'}; //any data
                          
                          List mapAsList = map.keys.toList(); //convert map to list to get iteration index
                          
                          print( map[mapAsList[0]] ); //first 
                          print( map[mapAsList[1]] ); //second
                          

                          【讨论】:

                            猜你喜欢
                            • 2011-05-12
                            • 2010-10-14
                            • 1970-01-01
                            • 1970-01-01
                            • 2017-08-01
                            • 2017-01-24
                            • 2023-04-04
                            • 2014-09-19
                            • 2020-05-21
                            相关资源
                            最近更新 更多