programing

다트에서 두 개의 목록을 결합하려면 어떻게 해야 합니까?

batch 2023. 4. 26. 23:08
반응형

다트에서 두 개의 목록을 결합하려면 어떻게 해야 합니까?

다트에서 두 개의 목록을 연결하여 완전히 새로운 목록 개체를 만드는 쉬운 방법이 있는지 궁금합니다.저는 아무것도 찾을 수 없었습니다.

내 목록:

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

다트 2부터는 이제 사용할 수 있습니다.+:

var newList = list1 + list2 + list3;

Dart 2.3부터는 스프레드 연산자를 사용할 수 있습니다.

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

아마 더 일관적일 것입니다.

var list = []..addAll(list1)..addAll(list2);

Dart는 이제 다음을 사용하여 목록 연결을 지원합니다.+교환입니다.

예:

List<int> result = [0, 1, 2] + [3, 4, 5];

두 개의 목록을 병합하고 중복 항목을 제거하려면 다음 작업을 수행할 수 있습니다.

var newList = [...list1, ...list2].toSet().toList(); 

알렉산드레스의 답변이 가장 좋지만 예에서 처럼 +를 사용하려면 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.

제 생각에는 세 번째 목록을 만들 필요가 없습니다.

사용:

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

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

addAll두 목록을 병합하는 가장 일반적인 방법입니다.

그러나 목록 목록을 연결하려면 다음 세 가지 기능 중 하나를 사용할 수 있습니다(아래 예).

  • expand - Itable의 각 요소를 0개 이상의 요소로 확장합니다.
  • fold - 컬렉션의 각 요소를 기존 값과 반복적으로 결합하여 컬렉션을 단일 값으로 줄입니다.
  • reduction - 제공된 함수를 사용하여 컬렉션의 요소를 반복적으로 결합하여 컬렉션을 단일 값으로 줄입니다.
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()고유 항목만 필터링하고 반환합니다.

다음은 또 다른 예입니다.

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>>따라서 다른 반복 가능 항목과도 작동합니다.

목록 중 하나가 무효인 경우...?연산자:

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

목록에서 중복 항목도 제거하려는 경우:

var newList = {
  ...?list1,
  ...?list2,
  ...?list3,
}.toList();
 list1.followedBy(list2).toList();

언급URL : https://stackoverflow.com/questions/21826342/how-do-i-combine-two-lists-in-dart

반응형