如何不转Int对单空格分隔数字字符串数组进行升序排序
问题
如何在不将元素转换为Int类型的前提下,对元素为单空格分隔数字格式字符串的数组执行升序排序?
初始直接使用字符串默认字典序排序的代码无法得到预期结果:
array = ["1 700", "50", "2 150", "2 100", "750", "3 250"] array.sort(by: { $0 < $1 }) print(array) // ["1 700", "2 100", "2 150", "3 250", "50", "750"]
预期排序结果为["50", "750", "1 700", "2 100", "2 150", "3 250"],该需求完全可以实现。
实现方案
默认字符串比较按逐字符字典序排序,空格的Unicode码值小于数字字符,才会导致带千位空格的字符串被排在前面。我们不需要把字符串转成Int,只需要利用正整数的比较规则,直接通过字符操作完成比对即可:
- 先过滤掉字符串中的空格,得到纯数字字符序列
- 优先比较纯数字序列的长度:长度越短代表数字位数越少,数值一定更小,排在前面
- 如果两个纯数字序列长度相同,从左到右逐位比对数字字符:数字字符"0"到"9"的Unicode码值连续递增,直接比较字符大小就能得到对应位的数值大小关系,第一个不同位上字符更小的字符串整体数值更小
- 所有字符都相同则两个字符串数值相等
对应实现代码:
var array = ["1 700", "50", "2 150", "2 100", "750", "3 250"] array.sort { a, b in let numCharsA = a.filter { $0 != " " } let numCharsB = b.filter { $0 != " " } // 位数不同时,位数少的数更小 guard numCharsA.count == numCharsB.count else { return numCharsA.count < numCharsB.count } // 位数相同时逐位比数字字符 for (charA, charB) in zip(numCharsA, numCharsB) { if charA != charB { return charA < charB } } return true } print(array) // 输出 ["50", "750", "1 700", "2 100", "2 150", "3 250"]
这个实现全程仅做字符级别的过滤、遍历、比较操作,没有将任何字符串元素转换为Int类型,运行结果完全符合预期。
内容的提问来源于stack exchange,提问作者Dmitry
相关产品推荐
相关产品推荐

