当前位置:  开发笔记 > 编程语言 > 正文

如何在JavaScript中对字符串进行排序

如何解决《如何在JavaScript中对字符串进行排序》经验,为你挑选了6个好方法。

我有一个我希望根据attr字符串类型字段排序的对象列表.我试过用-

list.sort(function (a, b) {
    return a.attr - b.attr
})

但发现-在JavaScript 中似乎不适用于字符串.如何根据类型字符串的属性对对象列表进行排序?



1> Shog9..:

使用String.prototype.localeCompare每个您的示例:

list.sort(function (a, b) {
    return ('' + a.attr).localeCompare(b.attr);
})

我们强制a.attr为字符串以避免异常.自Internet Explorer 6和Firefox 1 以来localeCompare一直受支持.您还可能会看到以下使用的代码不符合区域设置:

if (item1.attr < item2.attr)
  return -1;
if ( item1.attr > item2.attr)
  return 1;
return 0;


在任何人犯下与我一样的仓促错误之前,它是本地*e*比较,而不是localCompare.
第一个解决方案将在"z"之后但在"Z"之前考虑"A",因为它正在对字符ASCII值进行比较.`localeCompare()`不会遇到这个问题,但是不理解数字,所以你会得到["1","10","2"]和大多数语言中的排序比较一样.如果您想要对UI前端进行排序,请查看alphanum /自然排序算法http://stackoverflow.com/questions/4340227/sort-mixed-alpha-numeric-array或http://stackoverflow.com/questions/ 4321829 /字母数字-分拣中的java脚本
不,我的意思是表的第一行,@ Adrien - IE支持`localeCompare()`返回许多版本,但不支持*指定语言环境*直到版本11.还要注意Dead.Rabit链接的问题.
请注意,`localeCompare()`仅在现代浏览器中受支持:IE11 +在撰写本文时,请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare
@ Shog9我的不好,似乎它是IE6以来的支持!请参阅http://msdn.microsoft.com/en-us/library/ie/s4esdbwz(v=vs.94).aspx上的(向下滚动/搜索到localeCompare()方法).有一点需要注意,在旧的实现中,我们不使用locales和options参数(在IE11之前使用的参数)*使用的语言环境和排序顺序完全取决于实现*,换句话说:Firefox,Safari,Chrome& IE不会以相同的顺序对字符串进行排序.请参阅https://code.google.com/p/v8/issues/detail?id=459

2> Adrien Be..:

更新的答案(2014年10月)

我真的很烦恼这个字符串自然排序顺序,所以我花了很长时间来研究这个问题.我希望这有帮助.

长话短说

localeCompare()角色支持是坏蛋,只需使用它.正如所指出的Shog9,你的问题的答案是:

return item1.attr.localeCompare(item2.attr);

在所有自定义javascript"自然字符串排序顺序"实现中找到的错误

有很多自定义实现,尝试进行字符串比较更准确地称为"自然字符串排序顺序"

当"玩"这些实现时,我总是注意到一些奇怪的"自然排序顺序"选择,或者说错误(或者在最好的情况下的遗漏).

通常,不能正确处理特殊字符(空格,短划线,和号,括号等).

然后你会发现它们出现在不同的地方,通常可能是:

一些将在大写的'Z'和小写的'a'之间

一些将介于'9'和大写'A'之间

一些将在小写'z'之后

当人们期望特殊字符在一个地方被"分组"在一起时,除了空格特殊字符(可能始终是第一个字符).也就是说,要么全部在数字之前,要么全部在数字和字母之间(小写和大写一个接一个地"在一起"),或者全部在字母之后.

我的结论是,它们都未能提供一致的订单时,我开始增加几乎没有不寻常的字符(即用变音符号或charcters如破折号,感叹号等字符).

研究自定义实现:

Natural Compare Lite https://github.com/litejs/natural-compare-lite:在整理排序时失败https://github.com/litejs/natural-compare-lite/issues/1和http://jsbin.com/bevututodavi/ 1 /编辑?js,console,基本拉丁字符排序http://jsbin.com/bevututodavi/5/edit?js,console

Natural Sort https://github.com/javve/natural-sort:一致排序失败,请参阅问题https://github.com/javve/natural-sort/issues/7并查看排序http:// jsbin的基本拉丁字符. COM/cipimosedoqe/3 /编辑?JS,控制台

Javascript Natural Sort https://github.com/overset/javascript-natural-sort:自2012年2月以来似乎相当被忽视,一直排序失败,请参阅问题https://github.com/overset/javascript-natural-sort/issues/16

Alphanum http://www.davekoelle.com/files/alphanum.js,一致排序失败,请参阅http://jsbin.com/tuminoxifuyo/1/edit?js,console

浏览器的本机"自然字符串排序顺序"实现 localeCompare()

localeCompare()IE6 +支持最老的实现(没有locales和options参数),请参阅http://msdn.microsoft.com/en-us/library/ie/s4esdbwz (v=vs.94) .aspx(向下滚动到localeCompare( ) 方法).内置localeCompare()方法在排序方面做得更好,甚至包括国际和特殊字符.使用该localeCompare()方法的唯一问题是"使用的语言环境和排序顺序完全依赖于实现".换句话说,当使用localeCompare如stringOne.localeCompare(stringTwo)时:Firefox,Safari,Chrome和IE对字符串有不同的排序顺序.

研究浏览器本机实现:

http://jsbin.com/beboroyifomu/1/edit?js,console-与localeCompare()的 基本拉丁字符比较http://jsbin.com/viyucavudela/2/ - 与localeCompare()进行基本拉丁字符比较以进行测试IE8

http://jsbin.com/beboroyifomu/2/edit?js,console-字符串比较中的基本拉丁字符:字符串中的一致性检查

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare - IE11 +支持新的语言环境和选项参数

"字符串自然排序顺序"的难点

实现一个可靠的算法(意思是:一致但也涵盖广泛的字符)是一项非常艰巨的任务.UTF8包含超过2000个字符,涵盖120多种脚本(语言).最后,这个任务有一些规范,它被称为"Unicode校对算法",可以在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

你如何在JavaScript中进行字符串比较?

Javascript:自然的字母数字字符串

排序数字和字母元素的数组(自然排序)

对混合的字母/数字数组排序

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的好回答,这让我相信"正确"的方向



3> mpyw..:
答案(在现代ECMAScript中)
list.sort((a, b) => (a.attr > b.attr) - (a.attr < b.attr))

要么

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;


@RanLottem`localeCompare`和标准比较产生不同的结果.您对此有何看法?`["A","b","C","d"].sort((a,b)=> a.localeCompare(b))`用不区分大小写的字母顺序排序,而`["A", "b","C","d"].排序((a,b)=>(a> b) - (a
4> airportyh..:

你应该在这里使用>或<和==.所以解决方案是:

list.sort(function(item1, item2) {
    var val1 = item1.attr,
        val2 = item2.attr;
    if (val1 == val2) return 0;
    if (val1 > val2) return 1;
    if (val1 < val2) return -1;
});



5> Manav..:

我长期以来一直对此感到烦恼,所以我终于研究了这个并给你这个长期的理由,为什么事情就像他们一样.

从规格:

Section 11.9.4   The Strict Equals Operator ( === )

The production EqualityExpression : EqualityExpression === RelationalExpression
is evaluated as follows: 
- Let lref be the result of evaluating EqualityExpression.
- Let lval be GetValue(lref).
- Let rref be the result of evaluating RelationalExpression.
- Let rval be GetValue(rref).
- Return the result of performing the strict equality comparison 
  rval === lval. (See 11.9.6)

现在我们转到11.9.6

11.9.6   The Strict Equality Comparison Algorithm

The comparison x === y, where x and y are values, produces true or false. 
Such a comparison is performed as follows: 
- If Type(x) is different from Type(y), return false.
- If Type(x) is Undefined, return true.
- If Type(x) is Null, return true.
- If Type(x) is Number, then
...
- If Type(x) is String, then return true if x and y are exactly the 
  same sequence of characters (same length and same characters in 
  corresponding positions); otherwise, return false.

而已.如果参数完全相同的字符串(相应位置的相同长度和相同字符),则应用于字符串的三重等于运算符将返回true.

因此===,当我们尝试比较可能来自不同来源的字符串,但我们知道它们最终将具有相同的值时,这种情况会起作用 - 这是我们代码中内联字符串的常见情况.例如,如果我们有一个名为的变量connection_state,并且我们希望知道它['connecting', 'connected', 'disconnecting', 'disconnected']现在是以下哪个状态,我们可以直接使用===.

但还有更多.在11.9.4之上,有一个简短的说明:

NOTE 4     
  Comparison of Strings uses a simple equality test on sequences of code 
  unit values. There is no attempt to use the more complex, semantically oriented
  definitions of character or string equality and collating order defined in the 
  Unicode specification. Therefore Strings values that are canonically equal
  according to the Unicode standard could test as unequal. In effect this 
  algorithm assumes that both Strings are already in normalized form.

嗯.现在怎么办?外部获得的字符串可能,而且很可能会是奇怪的unicodey,而我们的温柔===将不会公正.在localeCompare救援中:

15.5.4.9   String.prototype.localeCompare (that)
    ...
    The actual return values are implementation-defined to permit implementers 
    to encode additional information in the value, but the function is required 
    to define a total ordering on all Strings and to return 0 when comparing
    Strings that are considered canonically equivalent by the Unicode standard. 

我们现在可以回家了.

TL;博士;

要比较javascript中的字符串,请使用localeCompare; 如果你知道字符串没有非ASCII组件,因为它们是,例如,内部程序常量,那么===也可以工作.



6> geckos..:

嵌套三元箭头功能

(a,b) => (a < b ? -1 : a > b ? 1 : 0)

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有