简体   繁体   English

如何定义默认的 JavaScript 排序回调函数?

[英]How to define default JavaScript sort callback function?

I'm attempting to create my own sort function (question Async version of sort function in JavaScript ).我正在尝试创建自己的排序函数(问题Async version of sort function in JavaScript )。 I've taken merge sort function from Rosetta Code and make it async:我从Rosetta Code中获取了合并排序功能并使其异步:

// based on: https://rosettacode.org/wiki/Sorting_algorithms/Merge_sort#JavaScript
async function mergeSort(fn, array) {
    if (array.length <= 1) {
        return array;
    }
    const mid = Math.floor(array.length / 2),
          left = array.slice(0, mid), right = array.slice(mid);
    await mergeSort(fn, left)
    await mergeSort(fn, right)
    let ia = 0, il = 0, ir = 0;
    while (il < left.length && ir < right.length) {
        array[ia++] = (await fn(left[il], right[ir]) <= 0) ? left[il++] : right[ir++];
    }
    while (il < left.length) {
        array[ia++] = left[il++];
    }
    while (ir < right.length) {
        array[ia++] = right[ir++];
    }
    return array;
}

But I'm not sure how I can define default function fn to work the same as in JavaScript.但我不确定如何定义默认函数 fn 以使其与 JavaScript 中的工作方式相同。

 console.log([1, 2, 3, 10, 11, 100, 20].sort());

What should be the default sorting function to match those in the JavaScript engine?与 JavaScript 引擎中的排序函数匹配的默认排序函数应该是什么? Should I convert numbers to strings and compare those?我应该将数字转换为字符串并进行比较吗? What is the proper implementation?什么是正确的实施?

Updated Answer更新的答案

The default sort method as defined in core.js looks like so core.js 中定义的默认sort方法如下所示

var getSortCompare = function (comparefn) {
  return function (x, y) {
    if (y === undefined) return -1;
    if (x === undefined) return 1;
    if (comparefn !== undefined) return +comparefn(x, y) || 0;
    return toString(x) > toString(y) ? 1 : -1;
  };

Taken from this repo: https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.sort.js取自这个仓库: https ://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.sort.js

Based on @jonrsharpe comments I was able to implement proper default function:基于@jonrsharpe 评论,我能够实现正确的默认功能:

function defaultSortFn(a, b) {
    if (typeof a !== 'string') {
        a = String(a);
    }
    if (typeof b !== 'string') {
        b = String(b);
    }
    if (a < b) {
        return -1;
    }
    if (a > b) {
        return 1;
    }
    return 0;
}

that can be used in my sort:可以用于我的排序:

Array.prototype.sort = function(fn = defaultSortFn) {
   return mergeSort(fn, this);
};

The ECMAScript specification for Arra.prototype.sort mentions that the comparison (in absence of a comparator) involves: Arra.prototype.sort的 ECMAScript 规范提到比较(在没有比较器的情况下)涉及:

e. e. Let xString be ?xString是 ? ToString( x ). ToString( x )。
f. F。 Let yString be ?yString是 ? ToString( y ). ToString( y )。
g. G。 Let xSmaller be !xSmaller成为! IsLessThan( xString , yString , true ). IsLessThan( xString , yString , true )。
h. H。 If xSmaller is true, return -1 𝔽 .如果xSmaller为真,则返回-1 𝔽
i.一世。 Let ySmaller be !y变小! IsLessThan( yString , xString , true ). IsLessThan( yString , xString , true )。
j. j. If ySmaller is true, return 1 𝔽 .如果ySmaller为真,则返回1 𝔽
k. ķ。 Return +0 𝔽 .返回+0 𝔽

Given that the IsLessThan procedure is also executed when two strings are compared with the < operator, we can faithfully replicate the default callback function as follows:考虑到 IsLessThan 过程也在用<运算符比较两个字符串时执行,我们可以忠实地复制默认回调函数,如下所示:

function (x, y) {
    let xString = String(x);
    let yString = String(y);
    return xString < yString ? -1 : yString < xString ? 1 : 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM