programing

속성 값을 기준으로 Float(Dart)의 개체 목록 정렬

goodjava 2023. 6. 4. 18:42

속성 값을 기준으로 Float(Dart)의 개체 목록 정렬

속성 중 하나의 알파벳 순으로 개체 목록을 정렬하는 방법(이름이 아니라 속성이 보유한 실제 값)?

비교 함수를 에 전달할 수 있습니다.

someObjects.sort((a, b) => a.someProperty.compareTo(b.someProperty));

일반적으로 에 사용자 지정 비교 기능을 제공할 수 있습니다.

/// Desired relation | Result
/// -------------------------------------------
///           a < b  | Returns a negative value.
///           a == b | Returns 0.
///           a > b  | Returns a positive value.
///
int mySortComparison(SomeClass a, SomeClass b) {
  final propertyA = someProperty(a);
  final propertyB = someProperty(b);
  if (propertyA < propertyB) {
    return -1;
  } else if (propertyA > propertyB) {
    return 1;
  } else {
    return 0;
  }
}

list.sort(mySortComparison);

사용자가 소유한 사용자 지정 클래스를 정렬하는 경우 클래스에서 다음 인터페이스를 구현하도록 할 수 있습니다.

class MyCustomClass implements Comparable<MyCustomClass> {
  ...

  @override
  int compareTo(MyCustomClass other) {
    if (someProperty < other.someProperty) {
      return -1;
    } else if (someProperty > other.someProperty) {
      return 1;
    } else {
      return 0;
    }
  }
}

그리고 나서 당신은 사용할 수 있습니다.list.sort()콜백을 제공하지 않고 직접.

로 정렬하는하십시오.Comparable비교 기능을 구현하는 것이 훨씬 더 간단합니다.예:

class MyCustomClass implements Comparable<MyCustomClass> {
  ...

  @override
  int compareTo(MyCustomClass other) =>
    someProperty.compareTo(other.someProperty);
}

후진

정렬 순서를 반대로 하려면 다음을 수행합니다.

  • 비교 함수가 반대 부호를 가진 값을 반환하도록 합니다.

  • 또는 정렬 후 목록을 명시적으로 반대로 전환합니다.

    list = (list..sort()).reversed.toList();
    

여러 속성별 정렬(예: 하위 정렬)

여러 속성별로 정렬하는 방법은 다양합니다.

  • 일반적인 방법은 중요성의 역순으로 각 속성에 대해 안정적인 정렬을 수행하는 것입니다.예를 들어, 이름을 주로 성으로 정렬한 다음 지정된 이름으로 성으로 정렬하려면 먼저 지정된 이름으로 정렬한 다음 안정적인 성으로 정렬합니다.안정적인 정렬 방법은 아래를 참조하십시오.

  • 또는 자체적으로 여러 속성을 확인하는 비교 함수를 사용하여 정렬할 수 있습니다.예:

    class Name {
      Name({String? surname, String? givenName})
        : surname = surname ?? "",
          givenName = givenName ?? "";
    
      final String surname;
      final String givenName;
    }
    
    int compareNames(Name name1, Name name2) {
      var comparisonResult = name1.surname.compareTo(name2.surname);
      if (comparisonResult != 0) {
         return comparisonResult;
      }
      // Surnames are the same, so subsort by given name.
      return name1.givenName.compareTo(name2.givenName);
    }
    
  • package:collection 에서는 체인 비교 기능의 확장 기능을 제공하므로 이러한 기능을 결합하는 것이 좀 더 간단하고 오류 발생 가능성이 낮습니다.

    import 'package:collection/collection.dart';
    
    int compareSurnames(Name name1, Name name2) =>
        name1.surname.compareTo(name2.surname);
    
    int compareGivenNames(Name name1, Name name2) =>
        name1.givenName.compareTo(name2.givenName);
    
    final compareNames = compareSurnames.then(compareGivenNames);
    
  • 내 패키지는 비교가 가능한 기능도 제공합니다.List중요도 순으로 속성 값 s:

    import 'package:dartbag/collection.dart';
    
    int compareNames(Name name1, Name name2) =>
      compareIterables(
        [name1.surname, name1.givenName],
        [name2.surname, name2.givenName],
      );
    

좋아요, 안정적인 타입을 원합니다.

List.sort안정적인 정렬이 보장되지 않습니다.안정적인 정렬이 필요한 경우 안정적인 제공 및 구현이 필요합니다.


하지만 비교하는 것은 비용이 많이 들 수 있습니다.

다음과 같은 사용자 정의 비교 기능이 있다고 가정합니다.

int compareMyCustomClass(MyCustomClass a, MyCustomClass b) {
  var a0 = computeValue(a);
  var b0 = computeValue(b);
  return a0.compareTo(b0);
}

정렬 프로세스에서 다음을 호출할 수 있습니다.computeValue동일한 객체에 대해 여러 번, 특히 다음과 같은 경우 낭비가 됩니다.computeValue()비쌉니다.이러한 경우 슈바르츠 변환은 (더 많은 메모리를 사용하는 대신) 더 빠를 수 있습니다.이 접근 방식은 개체를 직접 정렬 가능한 키에 매핑하고 키를 정렬한 다음 원래 개체를 추출합니다.(이것이 Python의 방식입니다.sort그리고.sorted기능이 작동합니다.)

다음은 가능한 구현 방법입니다.

class _SortableKeyPair<T, K extends Comparable<Object>>
    implements Comparable<_SortableKeyPair<T, K>> {
  _SortableKeyPair(this.original, this.key);

  final T original;
  final K key;

  @override
  int compareTo(_SortableKeyPair<T, K> other) => key.compareTo(other.key);
}

/// Returns a sorted *copy* of [items] according to the computed sort key.
List<E> sortedWithKey<E, K extends Comparable<Object>>(
  Iterable<E> items,
  K Function(E) toKey,
) {
  final keyPairs = [
    for (var element in items) _SortableKeyPair(element, toKey(element)),
  ]..sort();

  return [
    for (var keyPair in keyPairs) keyPair.original,
  ];
}

void main() {
  final list = <MyCustomClass>[ ... ];
  final sorted = sortedWithKeys(list, computeValue);
}

내 패키지는 그런 것을 제공합니다.sortWithKey함수(및 a)sortWithAsyncKey키를 비동기적으로 생성해야 하는 경우 함수).

속성 "name"을 기준으로 개체 "objects"를 정렬하려면 다음과 같은 작업을 수행합니다.

objects.sort((a, b) {
  return a.value['name'].toString().toLowerCase().compareTo(b.value['name'].toString().toLowerCase());
});    

불변 확장sortedBy리스트용.

extension MyIterable<E> on Iterable<E> {
  Iterable<E> sortedBy(Comparable key(E e)) =>
      toList()..sort((a, b) => key(a).compareTo(key(b)));
}

그리고 사용

list.sortedBy((it) => it.name);

여기 이 좋은 질문에 대한 저의 기여가 있습니다.@Nate Bosch 답변의 작동 방식을 이해하기 어려운 경우 사용자 지정 모델 클래스 목록을 정렬하려면 다음과 같이 하면 됩니다.

모델 클래스에서 추상 클래스를 구현해야 합니다.그것은 방법을 가지고 있습니다.compareTo당신이 무시해야 할 것입니다.예를 들어, 저는 이것을 가지고 있습니다.StudentMarks마크 속성이 있는 모델 클래스입니다.

class StudentMarks implements Comparable {
  int marks;

  StudentMarks({
    this.marks,
  });


  @override
  int compareTo(other) {

    if (this.marks == null || other == null) {
      return null;
    }

    if (this.marks < other.marks) {
      return 1;
    }

    if (this.marks > other.marks) {
      return -1;
    }

    if (this.marks == other.marks) {
      return 0;
    }

    return null;
  }
}

이제 전화할 수 있습니다.compareTo내부의 방법sort방법.

void _sortStudents({bool reversed: false}) {
    _students.sort((a, b) {
      return a.compareTo(b);
    });

    if (reversed) {
      _students = _students.reversed.toList();
    }

    setState(() {});
  }

자세한 내용은 이 링크를 참조하십시오.Comparable학급

https://api.dart.dev/stable/2.1.0/dart-core/Comparable-class.html

제게 효과가 있었습니다.

myList..sort((a, b) => a.name.toLowerCase().compareTo(b.name.toLowerCase()));

사용.Comparator함수, 정렬Users타고id.

Comparator<UserModel> sortById = (a, b) => a.id.compareTo(b.id);
users.sort(sortById);

이제 역순/하차순으로 정렬할 수 있습니다.

users = users.reversed.toList();

역순으로 정렬하기

list.sort((a, b) {
          return b.status.toLowerCase().compareTo(a.status.toLowerCase());
        });

또한 다음과 같이 보다 명확하게 사용할 수 있습니다.

class _Person {
  final int age;
  final String name;
  _Person({required this.age, required this.name});
}

void _test() {
  final array = [
    _Person(age: 10, name: 'Dean'),
    _Person(age: 20, name: 'Jack'),
    _Person(age: 30, name: 'Ben'),
  ];

  // ascend with age
  // Dean Jack Ben
  array.sort((p1, p2) {
    return Comparable.compare(p1.age, p2.age);
  });

  // decend with age
  // Ben Jack Dean
  array.sort((p1, p2) {
    return Comparable.compare(p2.age, p1.age);
  });

  // ascend with name
  // Ben Dean Jack
  array.sort((p1, p2) {
    return Comparable.compare(p1.name, p2.name);
  });
}

@pavel-shorokhovs 답변과 비슷하지만 강력하게 입력되었습니다.

extension IterableExtensions<T> on Iterable<T> {

  Iterable<T> sortBy<TSelected extends Comparable<TSelected>>(
      TSelected Function(T) selector) =>
  toList()..sort((a, b) => selector(a).compareTo(selector(b)));

  Iterable<T> sortByDescending<TSelected extends Comparable<TSelected>>(
      TSelected Function(T) selector) =>
  sortBy(selector).toList().reversed;

}

나는 fpgrow 기계 학습 출력/목록의 각 요소가 포함된 결과에 다른 목록과 주파수 필드가 포함되어 있습니다. 그래서 나는 그 시도를 위해 약간의 재귀를 사용했습니다. 나는 내가 늦었다는 것을 알고 있지만 아마도 다른 사람이 이익을 얻을 수 있을 것입니다.

 sort(List<FrequentItem> fqItems) {
    int len = fqItems.length;
    if(len==2){
      if(fqItems[0].frequency>fqItems[1].frequency){
        sortedItems.add(fqItems[0]);
        sortedItems.add(fqItems[1]);
      }else{
        sortedItems.add(fqItems[1]);
        sortedItems.add(fqItems[0]);
      }
      return;
    }else{
      FrequentItem max = fqItems[0];
      int index =0;
      for(int i=0;i<len-2;i++){
        if(max.frequency<fqItems[i+1].frequency){
          max = fqItems[i+1];
          index = i+1;
        }
      }
      sortedItems.add(max);
      fqItems.removeAt(index);
      sort(fqItems);
    }


  }

1단계: compareTo 메서드를 클래스에 추가합니다.

class Student {
  String? name;
  int? age;

  Student({this.name, this.age});

  int getAge() {
    if (age == null) return 0;
    return age!;
  }

  @override
  int compareTo(Student other) {
    var a = getAge();
    var b = other.getAge();

    if (a < b) {
      return -1;
    } else if (a > b) {
      return 1;
    } else {
      return 0;
    }
  }
}

2단계: 목록 정렬:

  • 오름차순:

    studentList.sort((a, b) {return a.compareTo(b); });

  • 내림차순:

    studentList.sort((a, b) {return b.compareTo(a); });

언급URL : https://stackoverflow.com/questions/53547997/sort-a-list-of-objects-in-flutter-dart-by-property-value