有没有办法按字符串内的数字对字符串列表进行排序?

yha*_*lza 1 dart flutter

有没有一种方法可以对类似的内容进行排序:

List<String> hi = ['1hi', '2hi','5hi', '3hi', '4hi'];
Run Code Online (Sandbox Code Playgroud)

对此?

['1hi', '2hi','3hi', '4hi', '5hi']
Run Code Online (Sandbox Code Playgroud)

jam*_*lin 5

只需调用List<String>.sort()本身即可进行词法排序。也就是说,你的字符串将按字符代码顺序排序,并且'10'会排在 之前'2'。这通常是意想不到的。

如果您的数字有前导s,则词法排序将起作用0,以确保所有数字具有相同的位数。但是,如果位数是可变的,您将需要解析数字的值以进行排序。更通用的方法是提供回调来.sort()告诉它如何确定两个项目的相对顺序。

幸运的是,package:collection有一个compareNatural函数可以为你做到这一点:

import 'package:collection/collection.dart';

List<String> hi = ['1hi', '2hi','5hi', '3hi', '4hi'];
hi.sort(compareNatural);
Run Code Online (Sandbox Code Playgroud)

如果您的情况有点复杂并且compareNatural没有执行您想要的操作,则更通用的方法是让.sort()回调自行解析,例如通过正则表达式:

/// Returns the integer prefix from a string.
///
/// Returns null if no integer prefix is found.
int parseIntPrefix(String s) {
  var re = RegExp(r'(-?[0-9]+).*');
  var match = re.firstMatch(s);
  if (match == null) {
    return null;
  }
  return int.parse(match.group(1));
}

int compareIntPrefixes(String a, String b) {
  var aValue = parseIntPrefix(a);
  var bValue = parseIntPrefix(b);
  if (aValue != null && bValue != null) {
    return aValue - bValue;
  }

  if (aValue == null && bValue == null) {
    // If neither string has an integer prefix, sort the strings lexically.
    return a.compareTo(b);
  }

  // Sort strings with integer prefixes before strings without.
  if (aValue == null) {
    return 1;
  } else {
    return -1;
  }
}

void main() {
  List<String> hi = ['1hi', '2hi','5hi', '3hi', '4hi'];
  hi.sort(compareIntPrefixes);
}
Run Code Online (Sandbox Code Playgroud)