我有一个对象列表,我希望基于类型字符串的字段attr进行排序。我试着用
list.sort(function (a, b) {
return a.attr - b.attr
})
但发现-似乎不适用于JavaScript中的字符串。我如何能排序基于类型字符串的属性的对象列表?
我有一个对象列表,我希望基于类型字符串的字段attr进行排序。我试着用
list.sort(function (a, b) {
return a.attr - b.attr
})
但发现-似乎不适用于JavaScript中的字符串。我如何能排序基于类型字符串的属性的对象列表?
当前回答
答案(现代ECMAScript)
list.sort((a, b) => (a.attr > b.attr) - (a.attr < b.attr))
Or
list.sort((a, b) => +(a.attr > b.attr) || -(a.attr < b.attr))
描述
将一个布尔值转换为一个数字会产生以下结果:
True -> 1 .单击“确定” False -> 0
考虑三种可能的模式:
X大于y: (X > y) - (y < X) -> 1 - 0 -> 1 X等于y:(X > y) - (y < X) -> 0 - 0 -> 0 X小于y:(X > y) - (y < X) -> 0 -1 -> -1
(替代)
x比y: + (x > y) | | - - - - - - (x < y) - > 1 | | 0 - > 1 x等于y: + (x > y) | | - - - - - - (x < y) - > 0 | | 0 - > 0 x小于y: + (x > y) | | - - - - - - (x < y) - > 0 | | 1 - > 1
这些逻辑等价于典型的排序比较器函数。
if (x == y) {
return 0;
}
return x > y ? 1 : -1;
其他回答
直接使用sort(),不带任何-或<
Const区域=['山','海滩','沙漠','山'] console.log (areas.sort ()) //以降序方式打印 .reverse console.log (areas.sort () ())
因为在javascript中可以直接比较字符串,所以这样做就可以了
list.sort(function (a, b) {
return a.attr < b.attr ? -1: 1;
})
这比使用更有效率
return a.attr > b.attr ? 1: -1;
因为如果元素具有相同的attr (a.t attr == b.t attr),排序函数将毫无理由地交换两者。
例如
var so1 = function (a, b) { return a.atr > b.atr ? 1: -1; };
var so2 = function (a, b) { return a.atr < b.atr ? -1: 1; }; // better
var m1 = [ { atr: 40, s: "FIRST" }, { atr: 100, s: "LAST" }, { atr: 40, s: "SECOND" } ].sort (so1);
var m2 = [ { atr: 40, s: "FIRST" }, { atr: 100, s: "LAST" }, { atr: 40, s: "SECOND" } ].sort (so2);
// m1 sorted but ...: 40 SECOND 40 FIRST 100 LAST
// m2 more efficient: 40 FIRST 40 SECOND 100 LAST
var str = ['v','a','da','c','k','l']
var b = str.join('').split('').sort().reverse().join('')
console.log(b)
更新答案(2014年10月)
我真的很讨厌这个字符串自然排序顺序,所以我花了一些时间来调查这个问题。
长话短说
localeCompare()字符支持是坏蛋,使用它。 正如Shog9所指出的,你的问题的答案是:
return item1.attr.localeCompare(item2.attr);
在所有自定义JavaScript“自然字符串排序顺序”实现中发现的错误
有相当多的自定义实现,试图进行字符串比较更精确地称为“自然字符串排序顺序”
当“玩”这些实现时,我总是注意到一些奇怪的“自然排序顺序”选择,或者说是错误(最好的情况下是遗漏)。
通常,特殊字符(空格、破折号、&号、括号等)不会被正确处理。
然后你会发现它们出现在不同的地方,通常情况下可能是:
有些介于大写字母Z和小写字母a之间 有些介于9和大写的A之间 有些会在小写z后面
当人们期望所有特殊字符都“分组”在一个地方时,除了空格特殊字符maybe(它总是第一个字符)。也就是说,要么全部在数字之前,要么全部在数字和字母之间(小写字母和大写字母一个接一个“在一起”),要么全部在字母之后。
我的结论是,当我开始添加几乎不寻常的字符(即带有变音符的字符或像破折号、感叹号等字符)时,它们都不能提供一致的顺序。
自定义实现研究:
Natural Compare Lite https://github.com/litejs/natural-compare-lite : Fails at sorting consistently https://github.com/litejs/natural-compare-lite/issues/1 and http://jsbin.com/bevututodavi/1/edit?js,console, basic Latin characters sorting http://jsbin.com/bevututodavi/5/edit?js,console Natural Sort https://github.com/javve/natural-sort : Fails at sorting consistently, see issue https://github.com/javve/natural-sort/issues/7 and see basic Latin characters sorting http://jsbin.com/cipimosedoqe/3/edit?js,console JavaScript Natural Sort https://github.com/overset/javascript-natural-sort: seems rather neglected since February 2012, Fails at sorting consistently, see issue https://github.com/overset/javascript-natural-sort/issues/16 Alphanum http://www.davekoelle.com/files/alphanum.js , Fails at sorting consistently, see http://jsbin.com/tuminoxifuyo/1/edit?js,console
通过localeCompare()实现浏览器的本地“自然字符串排序顺序”
localeCompare()最老的实现(没有locale和options参数)被Internet Explorer 6及更高版本所支持,请参阅http://msdn.microsoft.com/en-us/library/ie/s4esdbwz(v=vs.94).aspx(向下滚动到localeCompare()方法)。
内置的localeCompare()方法在排序方面做得更好,甚至是国际字符和特殊字符。
使用localeCompare()方法的唯一问题是“使用的语言环境和排序顺序完全依赖于实现”。换句话说,当使用localeCompare(如stringOne.localeCompare(stringTwo))时:Firefox、Safari、Chrome和Internet Explorer对字符串有不同的排序顺序。
浏览器原生实现研究:
http://jsbin.com/beboroyifomu/1/edit?js,console - basic Latin characters comparison with localeCompare() http://jsbin.com/viyucavudela/2/ - basic Latin characters comparison with localeCompare() for testing on Internet Explorer 8 http://jsbin.com/beboroyifomu/2/edit?js,console - basic Latin characters in string comparison : consistency check in string vs when a character is alone https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare - Internet Explorer 11 and later supports the new locales & options arguments
“字符串自然排序顺序”的难点
实现一个可靠的算法(意思是:一致但也涵盖广泛的字符)是一项非常艰巨的任务。UTF-8包含2000多个字符,涵盖120多种脚本(语言)。
最后,这个任务有一些规范,它被称为“Unicode Collation Algorithm”,可以在http://www.unicode.org/reports/tr10/上找到。关于这个问题,你可以在https://softwareengineering.stackexchange.com/questions/257286/is-there-any-language-agnostic-specification-for-string-natural-sorting-order上找到更多信息
最终结论
因此,考虑到目前我遇到的JavaScript自定义实现所提供的支持级别,我们可能永远不会看到任何东西接近于支持所有这些字符和脚本(语言)。因此,我宁愿使用浏览器的本地localeCompare()方法。是的,它确实有在不同浏览器之间不一致的缺点,但基本测试表明,它涵盖了更广泛的字符范围,允许稳定和有意义的排序顺序。
正如Shog9所指出的,你的问题的答案是:
return item1.attr.localeCompare(item2.attr);
进一步阅读:
https://softwareengineering.stackexchange.com/questions/257286/is-there-any-language-agnostic-specification-for-string-natural-sorting-order How to sort strings in JavaScript Natural sort of alphanumerical strings in JavaScript Sort Array of numeric & alphabetical elements (Natural Sort) Sort mixed alpha/numeric array https://web.archive.org/web/20130929122019/http://my.opera.com/GreyWyvern/blog/show.dml/1671288 https://web.archive.org/web/20131005224909/http://www.davekoelle.com/alphanum.html http://snipplr.com/view/36012/javascript-natural-sort/ http://blog.codinghorror.com/sorting-for-humans-natural-sort-order/
多亏了Shog9的回答,让我找到了我相信的“正确”方向。
在javascript中,我们使用.localCompare方法对字符串进行排序
为打印稿
const data = ["jane", "mike", "salome", "ababus", "buisa", "dennis"];
const sort = (arr: string[], mode?: 'desc' | 'asc') =>
!mode || mode === "asc"
? arr.sort((a, b) => a.localeCompare(b))
: arr.sort((a, b) => b.localeCompare(a));
console.log(sort(data, 'desc'));// [ 'salome', 'mike', 'jane', 'dennis', 'buisa', 'ababus' ]
console.log(sort(data, 'asc')); // [ 'ababus', 'buisa', 'dennis', 'jane', 'mike', 'salome' ]
对JS
const data = ["jane", "mike", "salome", "ababus", "buisa", "dennis"];
/**
* @param {string[]} arr
* @param {"asc"|"desc"} mode
*/
const sort = (arr, mode = "asc") =>
!mode || mode === "asc"
? arr.sort((a, b) => a.localeCompare(b))
: arr.sort((a, b) => b.localeCompare(a));
console.log(sort(data, 'desc'));// [ 'salome', 'mike', 'jane', 'dennis', 'buisa', 'ababus' ]
console.log(sort(data, 'asc')); // [ 'ababus', 'buisa', 'dennis', 'jane', 'mike', 'salome' ]