繁体   English   中英

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

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

我正在尝试创建自己的排序函数(问题Async version of sort function in JavaScript )。 我从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;
}

但我不确定如何定义默认函数 fn 以使其与 JavaScript 中的工作方式相同。

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

与 JavaScript 引擎中的排序函数匹配的默认排序函数应该是什么? 我应该将数字转换为字符串并进行比较吗? 什么是正确的实施?

更新的答案

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;
  };

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

基于@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;
}

可以用于我的排序:

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

Arra.prototype.sort的 ECMAScript 规范提到比较(在没有比较器的情况下)涉及:

e. xString是 ? ToString( x )。
F。 yString是 ? ToString( y )。
G。 xSmaller成为! IsLessThan( xString , yString , true )。
H。 如果xSmaller为真,则返回-1 𝔽
一世。 y变小! IsLessThan( yString , xString , true )。
j. 如果ySmaller为真,则返回1 𝔽
ķ。 返回+0 𝔽

考虑到 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