programing

다트 목록에서 중복된 항목을 삭제하려면 어떻게 해야 합니까?list.filength()를 선택합니다.

topblog 2023. 4. 18. 21:40
반응형

다트 목록에서 중복된 항목을 삭제하려면 어떻게 해야 합니까?list.filength()를 선택합니다.

세트를 가지고 장난치지 않고 목록에서 중복 항목을 삭제하려면 어떻게 해야 합니까?list.distinct()나 list.unique() 같은 것이 있습니까?

void main() {
  print("Hello, World!");

  List<String> list = ['abc',"abc",'def'];
  list.forEach((f) => print("this is list $f"));

  Set<String> set = new Set<String>.from(list);
  print("this is #0 ${list[0]}");
  set.forEach((f) => print("set: $f"));

  List<String> l2= new List<String>.from(set);
  l2.forEach((f) => print("This is new $f"));
}
Hello, World!
this is list abc
this is list abc
this is list def
this is #0 abc
set: abc
set: def
This is new abc
This is new def

세트가 훨씬 빠른 것 같아!!단, 아이템의 순서를 잃어버립니다./

사용하다toSet그리고 나서.toList

  var ids = [1, 4, 4, 4, 5, 6, 6];
  var distinctIds = ids.toSet().toList();

결과: [1, 4, 5, 6]

또는 산포 연산자의 경우:

var distinctIds = [...{...ids}];

나는 제공된 답변 중 어떤 것도 큰 도움이 되지 않았다.제가 주로 하는 일은 다음과 같습니다.

final ids = Set();
myList.retainWhere((x) => ids.add(x.id));

물론 개체를 고유하게 식별하는 모든 속성을 사용할 수 있습니다.꼭 그런 것만은 아닙니다.id들판.

다른 접근법에 비해 이점:

  • 목록의 원래 순서를 유지합니다.
  • 기본/해시 가능 유형뿐만 아니라 리치 오브젝트에도 사용 가능
  • 전체 목록을 세트로 복사한 후 목록으로 다시 복사할 필요가 없습니다.

업데이트: 09/12/21
목록에 대해 확장 방식을 한 번 선언할 수도 있습니다.

extension Unique<E, Id> on List<E> {
  List<E> unique([Id Function(E element)? id, bool inplace = true]) {
    final ids = Set();
    var list = inplace ? this : List<E>.from(this);
    list.retainWhere((x) => ids.add(id != null ? id(x) : x as Id));
    return list;
  }
}

이 확장 방법은 원래 답변과 동일합니다.사용방법:

// Use a lambda to map an object to its unique identifier.
myRichObjectList.unique((x) => x.id);
// Don't use a lambda for primitive/hashable types.
hashableValueList.unique();

Set정상적으로 동작하지만 순서가 유지되지는 않습니다.여기 다른 방법이 있습니다.LinkedHashSet:

import "dart:collection";

void main() {
  List<String> arr = ["a", "a", "b", "c", "b", "d"];
  List<String> result = LinkedHashSet<String>.from(arr).toList();
  print(result); // => ["a", "b", "c", "d"]
}

https://api.dart.dev/stable/2.4.0/dart-collection/LinkedHashSet/LinkedHashSet.from.html

다음을 시도해 보십시오.

List<String> duplicates = ["a", "c", "a"];

duplicates = duplicates.toSet().toList();

다트패드에서 이 코드를 확인합니다.

기본 유형보다 더 복잡한 개체를 계속 주문하려는 경우, 표시된 ID를 세트에 저장하고 세트에 이미 있는 ID를 필터링하여 제거합니다.

final list = ['a', 'a', 'b'];
final seen = Set<String>();
final unique = list.where((str) => seen.add(str)).toList();

print(unique); // => ['a', 'b']

//이 쉬운 방법은 잘 작동합니다.

List<String> myArray = [];
myArray = ['x', 'w', 'x', 'y', 'o', 'x', 'y', 'y', 'r', 'a'];

myArray = myArray.toSet().toList();

print(myArray);

// 결과 =>myArray =['x','w','y','o','r', 'a']

개체 목록에서 중복 제거:

class Stock {
  String? documentID; //key
  Make? make;
  Model? model;
  String? year;

  Stock({
    this.documentID,
    this.make,
    this.model,
    this.year,
  });
}

재고 리스트, 중복재고를 삭제할 장소

List<Stock> stockList = [stock1, stock2, stock3];

중복 제거

final ids = stockList.map((e) => e.documentID).toSet();
stockList.retainWhere((x) => ids.remove(x.documentID));

는 이것을 ATREON의 답변에 추가합니다.이 기능을 사용하고 싶은 사용자용Object:

class MyObject{
  int id;

  MyObject(this.id);


  @override
  bool operator ==(Object other) {
    return other != null && other is MyObject && hashCode == other.hashCode;
  }


  @override
  int get hashCode => id;
}

main(){
   List<MyObject> list = [MyObject(1),MyObject(2),MyObject(1)];

   // The new list will be [MyObject(1),MyObject(2)]
   List<MyObject> newList = list.toSet().toList();
}

Dart 2.3+ 를 사용하면, 다음과 같이 확산 연산자를 사용할 수 있습니다.

final ids = [1, 4, 4, 4, 5, 6, 6];
final distinctIds = [...{...ids}];

다음보다 가독성이 높은지 낮은지 여부ids.toSet().toList()독자가 결정하도록 하겠습니다:)

특정 리스트의 경우objectsEquatable 패키지를 사용할 수 있습니다.

예:

// ignore: must_be_immutable
class User extends Equatable {
  int id;
  String name;

  User({this.id, this.name});

  @override
  List<Object> get props => [id];
}

List<User> items = [
  User(
    id: 1,
    name: "Omid",
  ),
  User(
    id: 2,
    name: "Raha",
  ),
  User(
    id: 1,
    name: "Omid",
  ),
  User(
    id: 2,
    name: "Raha",
  ),
];

print(items.toSet().toList());

출력:

[User(1), User(2)]

여기, 유효한 솔루션이 있습니다.

var sampleList = ['1', '2', '3', '3', '4', '4'];
//print('original: $sampleList');
sampleList = Set.of(sampleList).toList();
//print('processed: $sampleList');

출력:

original: [1, 2, 3, 3, 4, 4]
processed: [1, 2, 3, 4]

fast_immutable_collections 패키지 사용:

[1, 2, 3, 2].distinct();

또는

[1, 2, 3, 2].removeDuplicates().toList();

주의: 사이distinct()새 목록을 반환합니다.removeDuplicates()를 돌려줌으로써 게으르게 한다.Iterable이는 추가 처리를 할 때 훨씬 더 효율적이라는 것을 의미합니다.예를 들어, 백만 개의 항목이 있는 목록이 있고 중복 항목을 제거하고 처음 5개를 얻으려고 한다고 가정합니다.

// This will process five items:
List<String> newList = list.removeDuplicates().take(5).toList();

// This will process a million items:
List<String> newList = list.distinct().sublist(0, 5);

// This will also process a million items:
List<String> newList = [...{...list}].sublist(0, 5);

두 방법 모두,by파라미터를 지정합니다.예를 들어 다음과 같습니다.

// Returns ["a", "yk", "xyz"]
["a", "yk", "xyz", "b", "xm"].removeDuplicates(by: (item) => item.length);

는, 이 정리한 입니다.removeDuplicates():

Iterable<T> removeDuplicates<T>(Iterable<T> iterable) sync* {
  Set<T> items = {};
  for (T item in iterable) {
    if (!items.contains(item)) yield item;
    items.add(item);
  }
}

주의: 저는 fast_immutable_collections 패키지의 저자 중 한 명입니다.

void uniqifyList(List<Dynamic> list) {
  for (int i = 0; i < list.length; i++) {
    Dynamic o = list[i];
    int index;
    // Remove duplicates
    do {
      index = list.indexOf(o, i+1);
      if (index != -1) {
        list.removeRange(index, 1);
      }
    } while (index != -1);
  }
}

void main() {
  List<String> list = ['abc', "abc", 'def'];
  print('$list');
  uniqifyList(list);
  print('$list');
}

출력:

[abc, abc, def]
[abc, def]

베스트 프랙티스 중 하나는 어레이를 정렬하여 중복 배제하는 것입니다.그 생각은 저급 언어에서 도용되었다.따라서 먼저 사용자 고유의 정렬을 만든 다음 서로 이어지는 동일한 값을 중복 배제합니다.

// Easy example
void dedup<T>(List<T> list, {removeLast: true}) {
  int shift = removeLast ? 1 : 0;
  T compareItem;
  for (int i = list.length - 1; i >= 0; i--) {
    if (compareItem == (compareItem = list[i])) {
      list.removeAt(i + shift);
    }
  }
}

// Harder example
void dedupBy<T, I>(List<T> list, I Function(T) compare, {removeLast: true}) {
  int shift = removeLast ? 1 : 0;
  I compareItem;
  for (int i = list.length - 1; i >= 0; i--) {
    if (compareItem == (compareItem = compare(list[i]))) {
      list.removeAt(i + shift);
    }
  }
}


void main() {
  List<List<int>> list = [[1], [1], [2, 1], [2, 2]];
  print('$list');
  dedupBy(list, (innerList) => innerList[0]);
  print('$list');

  print('\n removeLast: false');

  List<List<int>> list2 = [[1], [1], [2, 1], [2, 2]];
  print('$list2');
  dedupBy(list2, (innerList) => innerList[0], removeLast: false);
  print('$list2');
}

출력:

[[1], [1], [2, 1], [2, 2]]
[[1], [2, 1]]

removeLast: false
[[1], [1], [2, 1], [2, 2]]
[[1], [2, 2]]

이것도 다른 방법인데...

final reducedList = [];

list.reduce((value, element) {
    if (value != element) 
        reducedList.add(value);
    return element;
});

reducedList.add(list.last);

print(reducedList);

저는 좋아요.

var list = [
 {"id": 1, "name": "Joshua"},
 {"id": 2, "name": "Joshua"},
 {"id": 3, "name": "Shinta"},
 {"id": 4, "name": "Shinta"},
 {"id": 5, "name": "Zaidan"}
];
list.removeWhere((element) => element.name == element.name.codeUnitAt(1));
list.sort((a, b) => a.name.compareTo(b.name));

출력:

[{"id": 1, "name": "Joshua"}, 
{"id": 3, "name": "Shinta"}, 
{"id": 5, "name": "Zaidan"}]
List<Model> bigList = [];
List<ModelNew> newList = [];  

for (var element in bigList) {
      var list = newList.where((i) => i.type == element.type).toList();
      if(list.isEmpty){
       newList.add(element);
      }
    }

배열에서 중복을 제거하고 고유한 요소의 배열을 반환하는 메서드를 만듭니다.

class Utilities {
  static List<String> uniqueArray(List<String> arr) {
    List<String> newArr = [];
    for (var obj in arr) {
      if (newArr.contains(obj)) {
        continue;
      }
      newArr.add(obj);
    }
    return newArr;
  }
}

다음과 같은 방법으로 사용할 수 있습니다.

void main(List <String> args){
    List<int> nums = [1, 2, 2, 2, 3, 4, 5, 5];
    List<int> nums2 = nums.toSet().toList();
}

메모: 목록에 있는 항목이 클래스의 오브젝트이고 속성이 동일한 경우 이 기능은 작동하지 않습니다.이 문제를 해결하려면 다음 방법을 사용할 수 있습니다.

void main() {
  List<Medicine> objets = [Medicine("Paracetamol"),Medicine("Paracetamol"), Medicine("Benylin")];
  
  List <String> atributs = [];
  objets.forEach((element){
    atributs.add(element.name);
  });
  
  List<String> noDuplicates = atributs.toSet().toList();
  print(noDuplicates);
}

class Medicine{
  final String name;
  Medicine(this.name);
}

이것이 나의 해결책이다.

    List<T> removeDuplicates<T>(List<T> list, IsEqual isEqual) {
      List<T> output = [];
      for(var i = 0; i < list.length; i++) {
        bool found = false;
        for(var j = 0; j < output.length; j++) {
          if (isEqual(list[i], output[j])) {
            found = true;
          }
        }
        if (found) {
          output.add(list[i]);
        }
      }

      return output;
    }

다음과 같이 사용합니다.

  var theList = removeDuplicates(myOriginalList, (item1, item2) => item1.documentID == item2.documentID);

아니면...

  var theList = removeDuplicates(myOriginalList, (item1, item2) => item1.equals(item2));

아니면...

리액티브-다트라는 라이브러리가 있습니다.이 라이브러리에는 종료 및 비종단 시퀀스에 대한 많은 컴포지터블 연산자가 포함되어 있습니다.시나리오의 경우 다음과 같습니다.

final newList = [];
Observable
   .fromList(['abc', 'abc', 'def'])
   .distinct()
   .observe((next) => newList.add(next), () => print(newList));

산출량:

[abc, def]

비슷한 기능을 가진 다른 도서관이 있다는 것을 덧붙여야겠습니다.GitHub에서 확인해보시면 맞는 것을 찾을 수 있을 거예요.

언급URL : https://stackoverflow.com/questions/12030613/how-can-i-delete-duplicates-in-a-dart-list-list-distinct

반응형