如何在Dart中合并2个列表?

时间:2019-01-28 15:21:31

标签: dart flutter

我正在尝试合并2个列表,因此输出如下:

List<String> array1 = ["John", "Bob", "Fred", "June", "Tom"];
List<String> array2 = ["House", "Flat", "Bungalow"];

List<String> output = //["John", "House", "Bob", "Flat", "Fred", "Bungalow", "June", "Tom"]

我该如何实现?我看过颤动库中的zip函数,但它只返回一个列表,只要传递给它的最短列表即可。

EDIT :为澄清起见,我本质上希望与zip函数相同,但是如果一个数组比另一个数组长,我只想将剩余的项附加到末尾。

9 个答案:

答案 0 :(得分:3)

我不知道任何现成可用的东西,但这应该可以满足您的要求:

import 'dart:math' as math;

void main() {
  List<String> array1 = ["John", "Bob", "Fred", "June", "Tom"];
  List<String> array2 = ["House", "Flat", "Bungalow"];

  List<String> output = List<String>(array1.length + array2.length);
  int i = 0;
  for (i; i < math.min(array1.length, array2.length); i++) {
    output[i * 2] = array1[i];
    output[i * 2 + 1] = array2[i];
  }
  print(output);
  if (array1.length != array2.length) {
    if (array1.length > array2.length) {
      output.setRange(i * 2, output.length, array1.sublist(i));
    } else {
      output.setRange(i * 2, output.length, array2.sublist(i));
    }
  }
  print(output);
}

答案 1 :(得分:2)

以下是另一个解决方案,该解决方案的效率可能比Gunter的解决方案低,但实际上更具功能性,我喜欢就如何解决问题拥有多种观点。如果数组的长度如此之短,那么无论如何都不会考虑联接的优化。

此解决方案在最长数组的索引上创建一个可迭代的对象,并且对于每个索引i,如果i在两个数组中,则可能从输入数组中创建两个条目。否则,它仅包含包含i的数组中的元素。

import 'dart:math' as math;

main() {
  List<String> array1 = ["John", "Bob", "Fred", "June", "Tom"];
  List<String> array2 = ["House", "Flat", "Bungalow"];

  //["John", "House", "Bob", "Flat", "Fred", "Bungalow", "June", "Tom"]
  List<String> output =
      Iterable.generate(math.max(array1.length, array2.length))
          .expand((i) sync* {
    if (i < array1.length) yield array1[i];
    if (i < array2.length) yield array2[i];
  }).toList();

  print(output);
}

答案 2 :(得分:1)

我怀疑确实有一种核心方法确实可以满足您的需求。看看我的merge函数:

import 'dart:math';

List<String> merge(List<String> a, List<String> b) {
    List<String> output = [];

    var min_length = min(a.length, b.length);
    var max_length = max(a.length, b.length);

    for(var i = 0; i < min_length; i++) {
      output.add(a[i]);
      output.add(b[i]);
    }

    List<String> longer = a.length > b.length ? a : b;

    for(var i = min_length; i < max_length; i++) {
      output.add(longer[i]);
    }

    return output;
  }

void main() {
    merge(
      ["John", "Bob", "Fred", "June", "Tom"],
      ["House", "Flat", "Bungalow"]
    ).forEach((e) => print(e));

    print('------');

    merge(
      ["John", "Bob"],
      ["House", "Flat", "Bungalow"]
    ).forEach((e) => print(e));
}

答案 3 :(得分:0)

import 'package:queries/collections.dart';

void main() {
  var array1 = ["John", "Bob", "Fred", "June", "Tom"];
  var array2 = ["House", "Flat", "Bungalow"];
  var minLength = array1.length < array2.length ? array1.length : array2.length;
  var c1 = Collection(array1);
  var c2 = Collection(array2);
  var key1 = 0;
  var key2 = 0;
  //
  // 1. Join sequences by the index
  // 2. Flatten result
  // 3. Concat 1st rest
  // 4. Concat 2nd rest
  var query = c1
      .join(c2, (x) => key1++, (y) => key2++, (x, y) => <String>[x, y])
      .selectMany((e) => Collection(e))
      .concat(c1.skip(minLength))
      .concat(c2.skip(minLength));
  print(query.toList());
}

结果:

[John, House, Bob, Flat, Fred, Bungalow, June, Tom]

另一种方式:

import 'package:queries/collections.dart';

void main() {
  var array1 = ["John", "Bob", "Fred", "June", "Tom"];
  var array2 = ["House", "Flat", "Bungalow"];
  var minLength = array1.length < array2.length ? array1.length : array2.length;
  var c1 = Collection(array1);
  var c2 = Collection(array2);
  var query = c1
      .take(minLength)
      .select$1((e, i) => <String>[e, c2[i]])
      .selectMany((e) => Collection(e))
      .concat(c1.skip(minLength))
      .concat(c2.skip(minLength));
  print(query.toList());
}

另一种方式(带拉链):

import 'package:queries/collections.dart';

void main() {
  var array1 = ["John", "Bob", "Fred", "June", "Tom"];
  var array2 = ["House", "Flat", "Bungalow"];
  var minLength = array1.length < array2.length ? array1.length : array2.length;
  var c1 = Collection(array1);
  var c2 = Collection(array2);
  var query = c1
      .zip(c2, (x, y) => <String>[x, y])
      .selectMany((e) => Collection(e))
      .concat(c1.skip(minLength))
      .concat(c2.skip(minLength));
  print(query.toList());
}

下一步(懒惰,不需要知道长度)

void main() {
  var array1 = ["John", "Bob", "Fred", "June", "Tom"];
  var array2 = ["House", "Flat", "Bungalow"];
  print(merge(array1, array2));
}

Iterable<T> merge<T>(Iterable<T> c1, Iterable<T> c2) sync* {
  var it1 = c1.iterator;
  var it2 = c2.iterator;
  var active = true;
  while (active) {
    active = false;
    if (it1.moveNext()) {
      active = true;
      yield it1.current;
    }

    if (it2.moveNext()) {
      active = true;
      yield it2.current;
    }
  }
}

答案 4 :(得分:0)

我认为这也应该起作用

void main() {
  var list1 = ["John", "Bob", "Fred", "June", "Tom"];
  var list2 = ["House", "Flat", "Bungalow"];
  var list3 = [...list1, ...list2];

  print(list1);
  print(list2);
  print(list3);
}

输出应该是这样的(在DartPad中进行了测试)

[John, Bob, Fred, June, Tom]
[House, Flat, Bungalow]
[John, Bob, Fred, June, Tom, House, Flat, Bungalow]

答案 5 :(得分:0)

这里有很多好的答案,但是我想要更清楚一些,所以:

import 'dart:math' as math;

void main() {
  List<String> array1 = ["John", "Bob", "Fred", "June", "Tom"];
  List<String> array2 = ["House", "Flat", "Bungalow"];

  print(merge(array1, array2));
}

merge(List<String> left, List<String> right){
  List<String> result = [];

  for(int index = 0; index <= math.max(left.length, right.length); index++){
    safeAppend(left, result, index);
    safeAppend(right, result, index);
  }

  return result;
}

safeAppend(List<String> source, List<String> destination, int index){
  if(source.length > index){
    destination.add(source[index]);
  }
}

答案 6 :(得分:0)

您可以像使用addAll()方法。

List<int> a =[1,2];  List<int> b =[1,2];
List<int> c =[];
c.addAll(a);
c.addAll(b);

insertAll(index,Iterateable<>)

List<int> a =[1,2];  
List<int> b =[1,2];
a.insertAll(a.length,b);

   

答案 7 :(得分:0)

我也没有找到解决方案,如果可能的话,我也不想使用列表转换或数学函数,所以我这样写:

extension IterableExtensions<T> on Iterable<T> {
  Iterable<T> merge(Iterable<T> other) sync* {
    
    Iterator<T> iter1 = this.iterator;
    Iterator<T> iter2 = other.iterator;

    bool has1 = iter1.moveNext();
    bool has2 = iter2.moveNext();
    while(has1 && has2) {
      yield iter1.current;
      yield iter2.current;
      has1 = iter1.moveNext();
      has2 = iter2.moveNext();
    }
    while(has1) {
      yield iter1.current;
      has1 = iter1.moveNext();
    }
    while(has2) {
      yield iter2.current;
      has2 = iter2.moveNext();
    }
  }
}

可能可以整理一下,但目前可以使用。

示例here

答案 8 :(得分:0)

你可以使用expand

void main() {
  List<String> myList = ['a', 'b'];
  List<String> myList2 = ['a2', 'b2'];
  List<String> myList3 = [myList, myList2].expand((x) => x).toList();
  print(myList);  // [a, b]
  print(myList2); // [a, b]
  print(myList3); // [a, b, a2, b2]
}