76

我不喜欢使用索引数组,除了我认为它看起来很丑之外。有没有一种用匿名函数求和的干净方法?是否可以在不使用任何外部变量的情况下做到这一点?

4

13 回答 13

112

Dart iterables 现在有一个 reduce 函数(https://code.google.com/p/dart/issues/detail?id=1649),所以你可以在不定义自己的 fold 函数的情况下简单地做一个总结:

var sum = [1, 2, 3].reduce((a, b) => a + b);
于 2013-10-27T17:57:44.770 回答
100
int sum = [1, 2, 3].fold(0, (previous, current) => previous + current);

或使用更短的变量名称以使其占用更少的空间:

int sum = [1, 2, 3].fold(0, (p, c) => p + c);
于 2012-11-28T18:10:20.087 回答
25

这是一个非常古老的问题,但是

2021年其实有内置包

只需导入

import 'package:collection/collection.dart';

并调用.sum.Iterable

完整示例

import 'package:collection/collection.dart';

void main() {
  final list = [1, 2, 3, 4];
  final sum = list.sum;
  print(sum); // prints 10
}

如果列表为空,则.sum返回0

您可能还对list.average...感兴趣

于 2021-07-31T15:05:43.863 回答
24

对于这个特定问题,我仍然认为这更清晰,更容易理解。

num sum = 0;
[1, 2, 3].forEach((num e){sum += e;});
print(sum);

或者

num sum = 0;
for (num e in [1,2,3]) {
  sum += e;
}
于 2012-05-03T17:48:24.673 回答
9

没有像现在这样使用核心库的干净方法,但是如果你滚动你自己的foldLeft那么有

main() {
  var sum = foldLeft([1,2,3], 0, (val, entry) => val + entry);
  print(sum);
}

Dynamic foldLeft(Collection collection, Dynamic val, func) {
  collection.forEach((entry) => val = func(val, entry));
  return val;
}

我与 Dart 团队讨论了将foldLeft添加到核心集合中,我希望它很快就会出现。

于 2012-05-01T22:55:48.333 回答
3

从 Dart 2.6 开始,您可以使用扩展在 List 上定义实用方法。这适用于数字(示例 1),也适用于通用对象(示例 2)。

extension ListUtils<T> on List<T> {
  num sumBy(num f(T element)) {
    num sum = 0;
    for(var item in this) {
      sum += f(item);
    }
    return sum;
  }
}

示例 1(将列表中的所有数字相加):

var numbers = [1, 2, 3];
var sum = numbers.sumBy((number) => number);

示例 2(对所有 Point.x 字段求和):

var points = [Point(1, 2), Point(3, 4)];
var sum = points.sumBy((point) => point.x);
于 2019-10-25T04:28:33.557 回答
3

我建议您在任何常见的实用程序文件中创建此函数。

T sum<T extends num>(T lhs, T rhs) => lhs + rhs;

int、double、float 扩展了 num 类,因此您可以使用该函数对任何数字求和。

例如,

List<int> a = [1,2,3];
int result = a.reduce(sum);
print(result); // result will be 6
于 2019-12-18T09:37:14.780 回答
2

在此分享我的方法:

void main() {
  int value = sumTwo([1, 4, 3, 43]);
  print(value);
}

int sumTwo(List < int > numbers) {
  int sum = 0;

  for (var i in numbers) {
    sum = sum + i;
  }
  return sum;
}
于 2020-09-25T16:39:40.927 回答
1

如果使用 fold 时出现doubleTypeError,则可以使用 reduce:

var sum = [0.0, 4.5, 6.9].reduce((a, b) => a + b);
于 2021-09-02T00:15:16.223 回答
1

如果您计划对列表进行一些数学运算,通过扩展 ListBase 创建另一个包含 .sum() 和其他操作的列表类型可能会有所帮助。部分内容受到此响应的启发,并通过此响应进行了性能调整

import 'dart:collection';
import 'dart:core';

class Vector<num> extends ListBase<num> {
  
  List<num> _list;
  Vector() : _list = new List<num>();
  Vector.fromList(List<num> lst): _list = lst;
  
  void set length(int l) {
    this._list.length=l;
  }

  int get length => _list.length;
  
  num operator [](int index) => _list[index];

  void operator []=(int index, num value) {
    _list[index]=value;
  }
  // Though not strictly necessary, for performance reasons
  // you should implement add and addAll.

  void add(num value) => _list.add(value);

  void addAll(Iterable<num> all) => _list.addAll(all);
  
  num sum() => _list.fold(0.0, (a, b) => a + b) as num;
  /// add additional vector functions here like min, max, mean, factorial, normalize etc

}

并像这样使用它:

Vector vec1 = Vector();
vec1.add(1); 
print(vec1); // => [1]
vec1.addAll([2,3,4,5]); 
print(vec1); // => [1,2,3,4,5]
print(vec1.sum().toString()); // => 15
Vector vec = Vector.fromList([1.0,2.0,3.0,4.0,5.0]); // works for double too.
print(vec.sum().toString()); // => 15
于 2021-01-15T16:29:24.457 回答
0

查找所有飞镖列表元素总和的不同方法,

方法1:使用循环:这是最常用的方法。使用循环遍历列表并将列表的所有元素添加到最终的总和变量。我们在这里使用一个 for 循环:

main(List<String> args) {
  var sum = 0;
  var given_list = [1, 2, 3, 4, 5];

  for (var i = 0; i < given_list.length; i++) {
    sum += given_list[i];
  }

  print("Sum : ${sum}");
}

方法 2:使用 forEach : forEach 是另一种遍历列表的方法。我们也可以使用这种方法来找出 dart 列表中所有值的总和。它与上述方法类似。唯一的区别是我们不必初始化另一个变量 i 并且 list.length 不是必需的。

main(List<String> args) {
  var sum = 0;
  var given_list = [1, 2, 3, 4, 5];

  given_list.forEach((e) => sum += e);

  print("Sum : ${sum}");
}

方法 3:使用 reduce :reduce 方法使用给定函数迭代地将列表的所有元素组合为一个值。我们可以使用这种方法来找出所有元素的总和,如下所示:

main(List<String> args) {
  var given_list = [1, 2, 3, 4, 5];

  var sum = given_list.reduce((value, element) => value + element);

  print("Sum : ${sum}");
}

方法 4:使用 fold : fold() 类似于 reduce。它使用函数将列表的所有元素迭代地组合成一个值。它采用一个初始值并根据前一个值计算最终值。

main(List<String> args) {
  var sum = 0;
  var given_list = [1,2,3,4,5];

  sum = given_list.fold(0, (previous, current) => previous + current);

  print("Sum : ${sum}");
}

更多详情:https ://www.codevscolor.com/dart-find-sum-list-elements

于 2021-10-21T09:09:53.163 回答
0

对我来说干净的解决方案是:

var total => [1,2,3,4].fold(0, (e, t) => e + t); // result 10
于 2021-06-28T22:42:12.377 回答
0

我只想在@tmaihoff 的回答中添加一些小细节(关于使用collection.dart包):

sum他谈到的getter 仅适用于num值的可迭代对象,例如List<int>or Set<double>

如果您有代表值的其他对象类型的列表(如MoneyDecimalRational或任何其他),则必须将其映射到数字。例如,要计算字符串列表中的字符数,您可以执行以下操作:

// Returns 15.
['a', 'ab', 'abc', 'abcd', 'abcde'].map((e) => e.length).sum;

截至 2022 年,另一种方法是使用fast_immutable_collections包的sumBy()方法:

// Returns 15.
['a', 'ab', 'abc', 'abcd', 'abcde'].sumBy((e) => e.length), 15);

注意:我是包作者。

于 2022-02-07T23:55:49.910 回答