You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Dart/Flutter中按多个字段对列表排序

在Dart/Flutter中实现列表多字段排序

多字段排序的核心逻辑是按优先级链式比较:先按第一优先级字段排序,当该字段值相等时,再比较第二优先级字段,以此类推。下面用具体示例一步步说明实现方式。

1. 基础实现:原生Comparator链式比较

首先定义一个包含多字段的实体类,比如Person:

class Person {
  final String name;
  final int age;
  final double score;

  Person(this.name, this.age, this.score);

  @override
  String toString() => '$name, $age岁, 分数: $score';
}

然后利用List.sort()方法传入自定义的Comparator函数,按「年龄升序 → 分数降序 → 姓名升序」的优先级排序:

void main() {
  var people = [
    Person('Alice', 25, 85.5),
    Person('Bob', 22, 90.0),
    Person('Alice', 25, 92.0),
    Person('Charlie', 25, 85.5),
    Person('Bob', 22, 88.0),
  ];

  people.sort((a, b) {
    // 第一步:比较年龄(升序)
    final ageCompare = a.age.compareTo(b.age);
    if (ageCompare != 0) return ageCompare;

    // 第二步:年龄相等时,比较分数(降序,交换a、b位置实现)
    final scoreCompare = b.score.compareTo(a.score);
    if (scoreCompare != 0) return scoreCompare;

    // 第三步:分数也相等时,比较姓名(升序)
    return a.name.compareTo(b.name);
  });

  people.forEach(print);
}

运行后输出结果:

Bob, 22岁, 分数: 90.0
Bob, 22岁, 分数: 88.0
Alice, 25岁, 分数: 92.0
Alice, 25岁, 分数: 85.5
Charlie, 25岁, 分数: 85.5

关键逻辑说明

  • 每一步比较后,若返回值不为0(即两个对象在该字段上有大小差异),直接返回结果,终止后续比较;
  • 降序排序通过交换a和b的位置调用compareTo实现(比如b.score.compareTo(a.score));
  • 所有字段的比较优先级完全由代码中的顺序决定。

2. 优化:抽离比较逻辑(复杂场景)

如果排序逻辑复杂或需要复用,可以把比较逻辑抽成单独的函数:

// 独立的比较器函数
int comparePersons(Person a, Person b) {
  final ageCompare = a.age.compareTo(b.age);
  if (ageCompare != 0) return ageCompare;

  final scoreCompare = b.score.compareTo(a.score);
  if (scoreCompare != 0) return scoreCompare;

  return a.name.compareTo(b.name);
}

// 使用时直接传入函数
people.sort(comparePersons);

3. 简化方案:借助Equatable库

如果你使用equatable库(常用于简化实体类的相等性判断),可以利用它自动生成的compareTo方法快速实现多字段排序:

import 'package:equatable/equatable.dart';

class Person extends Equatable {
  final String name;
  final int age;
  final double score;

  Person(this.name, this.age, this.score);

  @override
  List<Object?> get props => [age, -score, name]; 
  // 按props顺序依次比较:age升序 → -score升序(等价于score降序)→ name升序
}

// 排序时直接使用默认的compareTo
people.sort((a, b) => a.compareTo(b));

这种方式适合简单的排序场景,注意数值类型的降序可以通过取负值实现,字符串类型则需要在compareTo中单独处理。


内容的提问来源于stack exchange,提问作者Andrey Sorokin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 05:40:41