203

I was wondering if there was an easy way to concatenate two lists in dart to create a brand new list object. I couldn't find anything and something like this:

My list:

list1 = [1, 2, 3]
list2 = [4, 5, 6]

I tried:

var newList = list1 + list2;

I wanted the combined output of:

[1, 2, 3, 4, 5, 6]
Cristik
  • 30,989
  • 25
  • 91
  • 127
Alex
  • 2,033
  • 2
  • 11
  • 7

13 Answers13

455

You can use:

var newList = new List.from(list1)..addAll(list2);

If you have several lists you can use:

var newList = [list1, list2, list3].expand((x) => x).toList()

As of Dart 2 you can now use +:

var newList = list1 + list2 + list3;

As of Dart 2.3 you can use the spread operator:

var newList = [...list1, ...list2, ...list3];
Alexandre Ardhuin
  • 71,959
  • 15
  • 151
  • 132
  • 29
    An alternative (which allows to easily concatenate many lists): `[list1, list2, list3, ...].expand((x) => x).toList()`; – Florian Loitsch Feb 17 '14 at 15:52
  • 6
    Note that the `+` operator cannot be be used on lists of different types. (in this case you get an error like `type 'List' is not a subtype of type 'List'`. ). The spread operator works great for this use case though. – Sébastien May 26 '20 at 14:19
  • Can you please check this question and suggest me something. https://stackoverflow.com/questions/62228799/flutter-merge-one-list-data-to-another-list#62228799 – Roxx Jun 06 '20 at 12:11
  • And what about performance? No answer is talking about that... – Dan Maia Apr 22 '23 at 22:43
21

maybe more consistent~

var list = []..addAll(list1)..addAll(list2);
Ticore Shih
  • 377
  • 2
  • 6
  • 3
    Old i know but what is the `..addAll()` why not just a single dot? – Abbas.M Jul 07 '19 at 07:23
  • 9
    @Abbas.M .. is for chaining, to do with out the double dot you would have to: list = []; list.addAll(list1); list.addAll(list2); The way I see it, it basically means call this function, but ignore what it returns, and keep operating on the object we were operating on. – csga5000 Aug 15 '19 at 21:56
21

Dart now supports concatenation of lists using the + operator.

Example:

List<int> result = [0, 1, 2] + [3, 4, 5];
Erlend
  • 1,711
  • 1
  • 22
  • 25
19

If you want to merge two lists and remove duplicates, you convert your final list to a Set using {} :

var newList = {...list1, ...list2}.toList(); 
Jack'
  • 1,722
  • 1
  • 19
  • 27
Adelina
  • 10,915
  • 1
  • 38
  • 46
10

Alexandres' answer is the best but if you wanted to use + like in your example you can use Darts operator overloading:

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
  }
}

Then:

var newMyList = myList1 + myList2;

Is valid :)

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
Daniel Robinson
  • 13,806
  • 18
  • 64
  • 112
7

I collect all possible method and benchmark it using benchmark_harness package.

According to the result the recommended method is:

  • final List<int> c = a + b;
  • final List<int> c = [...a, ...b];

Here is the benchmark code:

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();
}

And the result:

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.

nafsaka
  • 940
  • 2
  • 12
  • 17
4

If one of your list is nullable, use ...? operator:

var newList = [
  ...?list1,
  ...?list2,
  ...?list3,
];

If you also want to remove duplicate items in the list:

var newList = {
  ...?list1,
  ...?list2,
  ...?list3,
}.toList();
iDecode
  • 22,623
  • 19
  • 99
  • 186
3

No need to create a third list in my opinion...

Use this:

list1 = [1, 2, 3];
list2 = [4, 5, 6];
list1.addAll(list2);

print(list1); 
// [1, 2, 3, 4, 5, 6] // is our final result!
Llama
  • 465
  • 1
  • 8
  • 20
3

addAll is the most common way to merge two lists.

But to concatenate list of lists, you can use any of these three functions (examples below):

  • expand - Expands each element of an Iterable into zero or more elements,
  • fold - Reduces a collection to a single value by iteratively combining each element of the collection with an existing value,
  • reduce - Reduces a collection to a single value by iteratively combining elements of the collection using the provided function.
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]
}
Aleksandar
  • 3,558
  • 1
  • 39
  • 42
3

For Dart 2.3+ & the people from JavaScript community:

var mergedList = [...listX, ...listY, ...listZ].toSet(); 

toSet() will filter and return only unique items.

sid
  • 1,779
  • 8
  • 10
3

Here is another one:

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();

Note that flattened is defined as extension on Iterable<Iterable<T>> and hence also works with other iterables.

Stuck
  • 11,225
  • 11
  • 59
  • 104
2

Method 1 -> By using the addAll() function

var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
array1.addAll(array2); // array1 is now [1, 2, 3, 4, 5, 6]

Method 2 -> By using the loop.

var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
array2.forEach((item) {
   array1.add(item);
}); // array1 is now [1, 2, 3, 4, 5, 6]

Method 3 -> By using the + operator.

var array1 = [1, 2, 3];
var array1 = [4, 5, 6];
var newArray = array1 + array1;  // array1 is now [1, 2, 3, 4, 5, 6]
Anand
  • 4,355
  • 2
  • 35
  • 45
1
 list1.followedBy(list2).toList();
Yunus Kocatas
  • 286
  • 2
  • 9
  • 2
    It helps more if you supply an explanation why this is the preferred solution and explain how it works. We want to educate, not just provide code. – the Tin Man Feb 07 '22 at 05:09