Javascript 如何实现Array.prototype.sort默认比较函数? 背景
我需要实现一个与Array.prototype.sort的默认比较函数具有相同行为的函数 阅读文档后,我偶然发现: 默认排序顺序根据字符串Unicode代码点 这是什么意思?这是否意味着我将每个对象都转换为字符串 如果是这样,假设我有数组Javascript 如何实现Array.prototype.sort默认比较函数? 背景,javascript,sorting,Javascript,Sorting,我需要实现一个与Array.prototype.sort的默认比较函数具有相同行为的函数 阅读文档后,我偶然发现: 默认排序顺序根据字符串Unicode代码点 这是什么意思?这是否意味着我将每个对象都转换为字符串 如果是这样,假设我有数组[2,“a”,{hello:“world”}]这些步骤正确吗 将[2,“a”,{hello:“world”}]转换为[“2”,“a”,{hello:“world”}] 将每个字符串的第一个字符转换为数字 按那个号码订购 问题: 如何实现给定任何对象的比较函数,
[2,“a”,{hello:“world”}]
这些步骤正确吗
[2,“a”,{hello:“world”}]
转换为[“2”,“a”,{hello:“world”}]
comparefn
是undefined
,那么他们会使用此算法作为默认值:
有人能确认吗?看起来像是
和解决方案
在阅读了ECMA规范并四处询问之后,我找到了一个defaultCompare
函数,它模拟了chrome中Array.prototype.sort()的默认行为
const defaultCompare = ( x, y ) => {
//INFO: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
//ECMA specification: http://www.ecma-international.org/ecma-262/6.0/#sec-sortcompare
if( x === undefined && y === undefined )
return 0;
if( x === undefined )
return 1;
if( y === undefined )
return -1;
const xString = toString(x);
const yString = toString(y);
if( xString < yString )
return -1;
if( xString > yString )
return 1;
return 0;
};
const toString = obj => {
//ECMA specification: http://www.ecma-international.org/ecma-262/6.0/#sec-tostring
if( obj === null )
return "null";
if( typeof obj === "boolean" || typeof obj === "number" )
return (obj).toString();
if( typeof obj === "string" )
return obj;
if( typeof obj === "symbol" )
throw new TypeError();
//we know we have an object. perhaps return JSON.stringify?
return (obj).toString();
};
module.exports = defaultCompare;
如果在同一个浏览器中测试,输出应该相等。a不是ASCII和Unicode中表示的数字。.我已更新了我的问题,以便更清楚,请重新查看!检查规范中的算法:是数组排序的webkit实现。我不知道这是否有帮助,但看起来排序可能会根据内容采取几种不同的路径。我认为您的第二个代码块中有一个拼写错误,有一个句点看起来应该是逗号。另外,由于Array.prototype.sort
对数组进行了适当的排序,因此当您使用defaultCompare
对数组进行排序时,它已经被排序了一次。您应该制作一份数组副本,与第二个比较函数一起使用,以确保预排序不会影响项目的顺序。@philraj很好!我刚刚提交了一个带有那个点的编辑,还将卷曲的引号替换成了直引号。无论如何,这似乎是一个很好的默认比较函数。
const arr = [ undefined, null, 3, 2, 'B', 'a', 'b', 'A',
{ hello: "world"}, { goodnight: 'moon'} ]
assertEql( arr.sort(), arr.sort(defaultCompare) ); //true