按属性值对Flutter(Dart)中的对象列表进行排序

Nom*_*nom 12 dart flutter

任何想法如何按其属性之一的字母顺序排序对象列表(不是名称,而是属性保存的实际值)?

谢谢!

Nat*_*sch 30

您可以将比较功能传递给List.sort.

someObjects.sort((a, b) => a.someProperty.compareTo(b.someProperty));
Run Code Online (Sandbox Code Playgroud)

  • 要反转它,您可以执行“b.someProperty.compareTo(a.someProperty)”。或者对其进行排序,然后使用“.reversed”。 (12认同)
  • 你如何对它进行反向排序 (2认同)
  • 要反转,只需使用 (b,a) 代替 (a,b)。值得注意的是,如果您想要进行更高级的排序,compareTo 将返回 1、0 或 -1。 (2认同)

Con*_*ner 28

如果要按属性“名称”对对象“对象”进行排序,请执行以下操作

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


Rop*_*shi 14

这是我对这个好问题的贡献。如果有人难以理解@Nate Bosch 的答案是如何工作的,并且您想对自定义模型类列表进行排序,那么您可以这样做。

1. 你必须Comparable在你的模型类中实现抽象类。 它具有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;
  }
}
Run Code Online (Sandbox Code Playgroud)

2. 现在您可以在compareTo方法内部调用sort方法。

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

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

    setState(() {});
  }
Run Code Online (Sandbox Code Playgroud)

想了解更多Comparable课程请参考这个链接

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

  • 如果您要对正确实现“Comparable”的对象列表进行排序,则不需要使用回调显式调用“List.sort”;它应该是自动的。 (2认同)

mos*_*pha 14

它对我有用:

myList..sort((a, b) => a.name.toLowerCase().compareTo(b.name.toLowerCase()));
Run Code Online (Sandbox Code Playgroud)


jam*_*lin 11

通常,您可以向List.sort.

/// 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);
Run Code Online (Sandbox Code Playgroud)

如果您要对自己拥有的某个自定义类进行排序,您也可以让您的类实现该Comparable接口:

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;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后您可以list.sort()直接使用而无需提供回调。

请注意,如果您按已实现Comparable接口的单个属性进行排序,则实现比较函数要简单得多。例如:

class MyCustomClass implements Comparable<MyCustomClass> {
  ...

  @override
  int compareTo(MyCustomClass other) =>
    someProperty.compareTo(other.someProperty);
}
Run Code Online (Sandbox Code Playgroud)

倒车

如果你想颠倒排序顺序,你可以让你的比较函数返回一个符号相反的值。或者,只需在排序后显式反转列表:

list = (list..sort()).reversed.toList();
Run Code Online (Sandbox Code Playgroud)

按多个属性排序(又名子排序)

如果要按多个属性进行排序,一般的方法是按重要性相反的顺序对每个属性执行稳定排序。例如,如果您想首先按姓氏对姓名进行排序,然后按给名对姓氏进行子排序,那么您将首先按给名排序,然后按姓氏执行稳定排序。有关如何执行稳定排序的信息,请参见下文。

或者,您可以使用考虑多个属性的比较函数进行排序。例如:

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);
}
Run Code Online (Sandbox Code Playgroud)

好的,我想要一个稳定的排序

List.sort不是保证是一个稳定的排序。如果你需要一个稳定的排序,package:collection提供insertionSortmergeSort是稳定的实现。


但比较可能很昂贵

假设您有一个自定义比较函数,如下所示:

int compareMyCustomClass(MyCustomClass a, MyCustomClass b) {
  var a0 = computeValue(a);
  var b0 = computeValue(b);
  return a0.compareTo(b0);
}
Run Code Online (Sandbox Code Playgroud)

排序可能会computeValue()多次调用每个元素,如果computeValue()成本很高,这尤其浪费。在这种情况下,施瓦兹变换可能会更快(以使用更多内存为代价)。这种方法将您的对象映射到可直接排序的键,对键进行排序并提取原始对象。(这就是 Pythonsortsorted函数的工作方式。)

这是一种可能的实现:

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

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 当我想到“但是比较可能会很昂贵”时,我只是在想“我想知道作者将如何处理这个问题?” 又出现了。:) (3认同)

小智 11

要按相反顺序对其进行排序:

list.sort((a, b) {
          return b.status.toLowerCase().compareTo(a.status.toLowerCase());
        });
Run Code Online (Sandbox Code Playgroud)


com*_*m1x 10

sortedByList 的不可变扩展。

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

并使用

list.sortedBy((it) => it.name);
Run Code Online (Sandbox Code Playgroud)


无夜之*_*之星辰 9

更重要的是,你可以使用Comparable.compare更清晰的方式,例如:

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);
  });
}
Run Code Online (Sandbox Code Playgroud)


Nik*_*aab 7

类似于 @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;

}
Run Code Online (Sandbox Code Playgroud)


Par*_*iya 7

在 Dart/Flutter 中对对象列表进行排序

1使用自定义比较功能:

  class Customer {
    String name;
    int age;

    Customer(this.name, this.age);

    @override
    String toString() {
      return '{ ${this.name}, ${this.age} }';
    }
  }

  main() {
    List customers = [];
    customers.add(Customer('Jack', 23));
    customers.add(Customer('Adam', 27));
    customers.add(Customer('Katherin', 25));

    customers.sort((a, b) => a.age.compareTo(b.age));
    print('Sort by Age: ' + customers.toString());

    customers.sort((a, b) => a.name.compareTo(b.name));
    print('Sort by Name: ' + customers.toString());
  }
Run Code Online (Sandbox Code Playgroud)

输出:

Sort by Age: [{ Jack, 23 }, { Katherin, 25 }, { Adam, 27 }]
Sort by Name: [{ Adam, 27 }, { Jack, 23 }, { Katherin, 25 }]
Run Code Online (Sandbox Code Playgroud)

2第二种方法是扩展Comparable抽象类和覆盖compareTo()方法。现在我们不需要传递比较函数,我们只需调用list.sort()代替list.sort(compare).

class Customer extends Comparable {
  String name;
  int age;

  Customer(this.name, this.age);

  @override
  String toString() {
    return '{ ${this.name}, ${this.age} }';
  }

  // sort by Name (asc), then age (desc)
  @override
  int compareTo(other) {
    int nameComp = this.name.compareTo(other.name);
    if (nameComp == 0) {
      return -this.age.compareTo(other.age); // '-' for descending
    }
    return nameComp;
  }
}

main() {
 List customers = [];
  customers.add(Customer('Jack', 23));
  customers.add(Customer('Adam', 27));
  customers.add(Customer('Katherin', 25));
  customers.add(Customer('Jack', 32));

  customers.sort();
  print(customers);
}
Run Code Online (Sandbox Code Playgroud)

输出:

[{ Adam, 27 }, { Jack, 32 }, { Jack, 23 }, { Katherin, 25 }]
Run Code Online (Sandbox Code Playgroud)


San*_*rya 6

使用Comparator功能,排序Usersid

Comparator<UserModel> sortById = (a, b) => a.id.compareTo(b.id);
users.sort(sortById);
Run Code Online (Sandbox Code Playgroud)

现在我们可以按倒序/降序对其进行排序。

users = users.reversed.toList();
Run Code Online (Sandbox Code Playgroud)