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

字母数字字符串数组排序:字母开头在前、数字开头在后分别排序

Dart 按指定规则排序字母数字字符串

需求回顾

  • 以英文字母开头的字符串排在列表最前面,排序时不区分大小写
  • 以数字开头的字符串排在列表最后面,单独按原字符串规则排序
  • 预期输出:[apple, John, Umas, 32, 782Agh1]

原代码问题分析

你的代码核心逻辑方向是对的,但在处理「一个以数字开头、一个以字母开头」的场景时,返回值逻辑错误:

  • 当name1以数字开头、name2以字母开头时,你用了return name2.compareTo(name1),这会导致字符串比较的结果干扰排序优先级,正确的做法是直接返回正数,让数字开头的字符串排到后面
  • 同理,当name1以字母开头、name2以数字开头时,应该返回负数,确保字母开头的字符串排在前面

修正后的代码

void main() {
  List<String> names = ['782Agh1', 'Umas', 'apple', 'John', '32'];

  names.sort((String name1, String name2) {
    bool n1StartsWithDigit = name1.startsWith(RegExp(r'[0-9]'));
    bool n2StartsWithDigit = name2.startsWith(RegExp(r'[0-9]'));

    // 两者都是字母开头:不区分大小写排序
    if (!n1StartsWithDigit && !n2StartsWithDigit) {
      return name1.toLowerCase().compareTo(name2.toLowerCase());
    }
    // name1是数字开头,name2是字母开头:name1排后面,返回正数
    if (n1StartsWithDigit && !n2StartsWithDigit) {
      return 1;
    }
    // name1是字母开头,name2是数字开头:name1排前面,返回负数
    if (!n1StartsWithDigit && n2StartsWithDigit) {
      return -1;
    }
    // 两者都是数字开头:按原字符串排序
    return name1.compareTo(name2);
  });

  print(names); // 输出:[apple, John, Umas, 32, 782Agh1]
}

逻辑解释

  1. 先判断两个字符串的开头类型,分成四类场景处理
  2. 字母开头组内部排序:统一转成小写后比较,实现不区分大小写的排序效果
  3. 数字开头组内部排序:直接用字符串默认的比较规则排序
  4. 跨组比较时,直接通过返回固定的正负值来确定优先级,避免字符串比较的干扰

内容的提问来源于stack exchange,提问作者John Paul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 21:45:32