枚举或映射Dart中具有索引和值的列表

时间:2019-02-27 05:42:06

标签: dart flutter

在飞镖中,有任何等同于普通的东西:

enumerate(List) -> Iterator((index, value) => f)
or 
List.enumerate()  -> Iterator((index, value) => f)
or 
List.map() -> Iterator((index, value) => f)

这似乎是最简单的方法,但是对于该功能不存在仍然感到奇怪。

Iterable<int>.generate(list.length).forEach( (index) => {
  newList.add(list[index], index)
});

编辑:

由于@ hemanth-raj,我得以找到所需的解决方案。 我将它放在这里,供需要执行类似操作的任何人使用。

List<Widget> _buildWidgets(List<Object> list) {
    return list
        .asMap()
        .map((index, value) =>
            MapEntry(index, _buildWidget(index, value)))
        .values
        .toList();
}

12 个答案:

答案 0 :(得分:11)

有一个asMap方法将列表转换为映射,其中键是索引,值是索引中的元素。请看一下文档here

示例:

List _sample = ['a','b','c'];
_sample.asMap().forEach((index, value) => f);

希望这会有所帮助!

答案 1 :(得分:10)

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

如果像我一样,您不喜欢仅为简单索引构建Map(数据结构)的想法,那么您可能想要的是一个map(函数),它可以为您提供索引。让我们称之为mapIndexed(就像在Kotlin中一样):

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

mapIndexed的实现很简单:

Iterable<E> mapIndexed<E, T>(
    Iterable<T> items, E Function(int index, T item) f) sync* {
  var index = 0;

  for (final item in items) {
    yield f(index, item);
    index = index + 1;
  }
}

答案 2 :(得分:4)

为方便起见,您可以使用此扩展方法。

extension CollectionUtil<T> on Iterable<T>  {

  Iterable<E> mapIndexed<E, T>(E Function(int index, T item) transform) sync* {
    var index = 0;

    for (final item in this) {
      yield transform(index, item as T);
      index++;
    }
  }
}

答案 3 :(得分:4)

您可以使用 ObjectMapper oMapper = new ObjectMapper(); List<Map> yourList=new ArrayList<Map>(); List<WorkEntry> list=q.getResultList(); for(WorkEntry we:list){ yourList.add(oMapper.convertValue(we , Map.class); } 工厂。以下代码将使用索引和值映射 Iterable.generate

Iterable

答案 4 :(得分:3)

使用 asMap 将列表首先转换为地图。元素的索引是关键。元素成为价值。使用条目将键和值映射到所需的任何内容。

List rawList = ["a", "b", "c"];
List<String> argList = rawList.asMap().entries.map((e) => '${e.key}:${e.value}').toList();
print(argList);

输出:

[0:a, 1:b, 2:c]

答案 5 :(得分:2)

以@Hemanth Raj答案为基础。

可以将其转换回去

List<String> _sample = ['a', 'b', 'c'];
_sample.asMap().values.toList(); 
//returns ['a', 'b', 'c'];

或者如果您需要映射函数的索引,则可以执行以下操作:

_sample
.asMap()
.map((index, str) => MapEntry(index, str + index.toString()))
.values
.toList();
// returns ['a0', 'b1', 'c2']

答案 6 :(得分:1)

Lukas Renggli的more软件包包括许多有用的工具,其中包括“索引”工具,它可以完全满足您的需求。从文档中:

indexed(['a', 'b'], offset: 1)
  .map((each) => '${each.index}: ${each.value}')
  .join(', ');

(除非您具有Smalltalk背景,否则您可以忽略offset参数。)

答案 7 :(得分:1)

要枚举或映射Dart中具有索引和值的列表,您可以使用提供这种功能的扩展方法。它称为select
以下是使用此方法的示例。

import 'package:enumerable/enumerable.dart';

void main() {
  final list = ['one', 'two', 'three'];

  final result1 = list.select$1((element, index) => MapEntry(index, element));
  print(result1);

  final result2 = list
      .select$1((element, index) => MapEntry(index, element))
      .toMap$1((kv) => kv.key, (kv) => kv.value);
  print(result2);

  var index = 0;
  final result3 = list.toMap((key) => index++);
  print(result3);
}

结果:

(MapEntry(0: one), MapEntry(1: two), MapEntry(2: three))
{0: one, 1: two, 2: three}
{0: one, 1: two, 2: three}

答案 8 :(得分:1)

最初,我认为['one', 'two', 'three'].asMap().forEach((index, value) { ... });的效率很低,因为它似乎将列表转换为地图。实际上不是-文档说它创建了列表的不可变 view 。我仔细检查了这段代码的dart2js

void main() {
  final foo = ['one', 'two', 'three'];
  foo.asMap().forEach((idx, val) {
    print('$idx: $val');
  });
}

它生成很多代码!但是要点是:

  main: function() {
    var foo = H.setRuntimeTypeInfo(["one", "two", "three"], ...);
    new H.ListMapView(foo, ...).forEach$1(0, new F.main_closure());
  },

  H.ListMapView.prototype = {
    forEach$1: function(_, f) {
      var t1, $length, t2, i;
      ...
      t1 = this._values;
      $length = t1.length;
      for (t2 = $length, i = 0; i < $length; ++i) {
        if (i >= t2)
          return H.ioore(t1, i);
        f.call$2(i, t1[i]);
        t2 = t1.length;
        if ($length !== t2)
          throw H.wrapException(P.ConcurrentModificationError$(t1));
      }
    },
    ...
  },

  F.main_closure.prototype = {
    call$2: function(idx, val) {
      ...
      H.printString("" + idx + ": " + H.S(val));
    },
    $signature: 1
  };

所以做高效的事情足够聪明!很聪明。

当然,您也可以只使用普通的for循环:

for (var index = 0; index < values.length; ++index) {
  final value = values[index];

答案 9 :(得分:1)

从Dart 2.7开始,您可以使用extension扩展Iterable的功能,而不必编写帮助程序方法

extension ExtendedIterable<E> on Iterable<E> {
  /// Like Iterable<T>.map but callback have index as second argument
  Iterable<T> mapIndex<T>(T f(E e, int i)) {
    var i = 0;
    return this.map((e) => f(e, i++));
  }

  void forEachIndex(void f(E e, int i)) {
    var i = 0;
    this.forEach((e) => f(e, i++));
  }
}

用法:

final inputs = ['a', 'b', 'c', 'd', 'e', 'f'];
final results = inputs
  .mapIndex((e, i) => 'item: $e, index: $i')
  .toList()
  .join('\n');

print(results);

// item: a, index: 0
// item: b, index: 1
// item: c, index: 2
// item: d, index: 3
// item: e, index: 4
// item: f, index: 5
inputs.forEachIndex((e, i) => print('item: $e, index: $i'));

// item: a, index: 0
// item: b, index: 1
// item: c, index: 2
// item: d, index: 3
// item: e, index: 4
// item: f, index: 5

答案 10 :(得分:1)

使用 dart collection package 您可以访问各种列表扩展

一个是mapIndexed

Iterable<R> mapIndexed<R>(R Function(int, E) convert)

list of all iterable extensions

答案 11 :(得分:-1)

您可以使用 collections 包中的 mapIndexed 扩展:

import 'package:collection/collection.dart';

void main() {
  final nums = [1, 2, 3];
  final strs = nums.mapIndexed((index, element) => index.toString() + '_' + element.toString()).toList();

  print(strs); //  [0_1, 1_2, 2_3]
}