我在想,有没有一种简单的方法可以在Dart中连接两个列表以创建一个全新的列表对象。我找不到任何东西,像这样的东西:
我的列表:
list1 = [1, 2, 3]
list2 = [4, 5, 6]
我尝试过:
var newList = list1 + list2;
我想要合并输出以下内容:
[1, 2, 3, 4, 5, 6]
我在想,有没有一种简单的方法可以在Dart中连接两个列表以创建一个全新的列表对象。我找不到任何东西,像这样的东西:
我的列表:
list1 = [1, 2, 3]
list2 = [4, 5, 6]
我尝试过:
var newList = list1 + list2;
我想要合并输出以下内容:
[1, 2, 3, 4, 5, 6]
你可以使用:
var newList = new List.from(list1)..addAll(list2);
如果您有多个列表,可以使用:
var newList = [list1, list2, list3].expand((x) => x).toList()
从Dart 2开始,您现在可以使用+
:
var newList = list1 + list2 + list3;
从Dart 2.3版本开始,您可以使用扩展运算符:
var newList = [...list1, ...list2, ...list3];
可能更加一致~
var list = []..addAll(list1)..addAll(list2);
{}
将最终的列表转换为一个 Set
:var newList = {...list1, ...list2}.toList();
var newList = {...list1, ...list2}.toList();
- SassanAlexandres的答案是最好的,但如果你想在你的例子中使用+,你可以使用Darts运算符重载:
class MyList<T>{
List<T> _internal = new List<T>();
operator +(other) => new List<T>.from(_internal)..addAll(other);
noSuchMethod(inv){
//pass all calls to _internal
}
}
那么:
var newMyList = myList1 + myList2;
有效的 :)
我收集了所有可能的方法,并使用benchmark_harness包进行基准测试。
根据结果,推荐的方法是:
final List<int> c = a + b;
final List<int> c = [...a, ...b];
以下是基准测试代码:
import 'package:benchmark_harness/benchmark_harness.dart';
List<int> a = [1, 2, 3];
List<int> b = [4, 5, 6];
class Benchmark1 extends BenchmarkBase {
const Benchmark1() : super('c = a + b ');
@override
void run() {
final List<int> c = a + b;
}
}
class Benchmark2 extends BenchmarkBase {
const Benchmark2() : super('c = a.followedBy(b).toList() ');
@override
void run() {
final List<int> c = a.followedBy(b).toList();
}
}
class Benchmark3 extends BenchmarkBase {
const Benchmark3() : super('c = [a, b].expand((x) => x).toList() ');
@override
void run() {
final List<int> c = [a, b].expand((x) => x).toList();
}
}
class Benchmark4 extends BenchmarkBase {
const Benchmark4() : super('c = [a, b].reduce((value, element) => value + element) ');
@override
void run() {
final List<int> c = [a, b].reduce((value, element) => value + element);
}
}
class Benchmark5 extends BenchmarkBase {
const Benchmark5() : super('c = [a, b].fold([], (previousValue, element) => previousValue + element) ');
@override
void run() {
final List<int> c = [a, b].fold([], (previousValue, element) => previousValue + element);
}
}
class Benchmark6 extends BenchmarkBase {
const Benchmark6() : super('a.addAll(b) ');
@override
void run() {
a.addAll(b);
}
}
class Benchmark7 extends BenchmarkBase {
const Benchmark7() : super('c = <int>[...a, ...b] ');
@override
void run() {
final List<int> c = <int>[...a, ...b];
}
}
class Benchmark8 extends BenchmarkBase {
const Benchmark8() : super('c = List.from(a)..addAll(b) ');
@override
void run() {
final List<int> c = List.from(a)..addAll(b);
}
}
void main() {
// Benchmark1().report();
// Benchmark2().report();
// Benchmark3().report();
// Benchmark4().report();
// Benchmark5().report();
// Benchmark6().report();
// Benchmark7().report();
Benchmark8().report();
}
结果如下:
c = a + b (RunTime): 0.8384643860155879 us.
c = a.followedBy(b).toList() (RunTime): 1.3018350015264015 us.
c = [a, b].expand((x) => x).toList() (RunTime): 2.194391139053011 us.
c = [a, b].reduce((value, element) => value + element) (RunTime): 1.1215188056273329 us.
c = [a, b].fold([], (previousValue, element) => previousValue + element) (RunTime): 1.7163271628511283 us.
a.addAll(b) (RunTime): 1.08603684815237 us.
c = <int>[...a, ...b] (RunTime): 0.8498483658053312 us.
c = List.from(a)..addAll(b) (RunTime): 0.9107294347150762 us.
...?
运算符:var newList = [
...?list1,
...?list2,
...?list3,
];
var newList = {
...?list1,
...?list2,
...?list3,
}.toList();
import 'package:collection/collection.dart';
final x = [1, 2, 3];
final y = [4, 5, 6];
final z = [x, y].flattened // Iterable<int>
final result = z.toList();
flattened
是作为 Iterable<Iterable<T>>
的扩展定义的,因此也适用于其他可迭代对象。import 'package:collection/collection.dart';
。 - Alexander KremenchukaddAll
是合并两个列表最常用的方式。
但是如果要连接多个列表,可以使用以下三个函数之一(下面是 示例):
void main() {
List<int> a = [1,2,3];
List<int> b = [4,5];
List<int> c = [6];
List<List<int>> abc = [a,b,c]; // list of lists: [ [1,2,3], [4,5], [6] ]
List<int> ints = abc.expand((x) => x).toList();
List<int> ints2 = abc.reduce((list1,list2) => list1 + list2);
List<int> ints3 = abc.fold([], (prev, curr) => prev + curr); // initial value is []
print(ints); // [1,2,3,4,5,6]
print(ints2); // [1,2,3,4,5,6]
print(ints3); // [1,2,3,4,5,6]
}
对于Dart 2.3+和来自JavaScript社区的人:
var mergedList = [...listX, ...listY, ...listZ].toSet();
toSet()
方法将过滤并返回唯一的元素。
[list1, list2, list3, ...].expand((x) => x).toList()
; - Florian Loitsch+
运算符不能用于不同类型的列表。(在这种情况下,您会收到类似“type 'List<Widget>' is not a subtype of type 'List<Image>'” 的错误信息。)但是展开运算符对此情况非常有效。 - Sébastien