【问题标题】:How does native sort method deal with sparse arrays原生排序方法如何处理稀疏数组
【发布时间】:2019-06-21 14:30:34
【问题描述】:

当一个稀疏数组被排序[5, 2, 4, , 1].sort() -> [1, 2, 4, 5, empty]时,无论return语句如何,即使有回调,空值也总是最后。

我正在构建自己的排序方法作为挑战,我通过使用过滤器方法解决了这个问题,因为过滤器会跳过空值。然后迭代过滤数组并将原始数组的索引设置为过滤数组的值。然后我缩短了原始数组的长度,因为剩余的项目将是重复的,我终于可以在我的排序算法中提供它。完成后,我将它的长度设置回原来的,最后添加适当数量的空项目。这是一段 sn-p 代码,但这里是 a link of the entire code

const collectUndefined = [];

// remove empty items and collect undefined
const removeSparse = this.filter(el => {
  if (el === undefined) {
    collectUndefined.push(el);
  }

  return el !== undefined;
});

const tempLength = this.length;

// reset values but will contain duplicates at the end
for (let i = 0; i < removeSparse.length; i++) {
  this[i] = removeSparse[i];
}

// shorten length which will remove extra duplicates
this.length = removeSparse.length;



// sort algorithm ...



// place undefineds back into the array at the end
this.push(...collectUndefined);

// restores original length and add empty elemnts at the end
this.length = tempLength;
return this

在处理稀疏数组时是否以这种类似的方式实现原生排序,或者没有。

【问题讨论】:

  • 这与插槽为空无关。它们只是非数字的,因此它们和数字之间的所有(不)等式都返回false。这可能是算法中的一个实现细节导致它们被移到最后,并且不太可能是规范的一部分。毕竟,JavaScript 中的内置排序是不稳定的。
  • 注意:[5, 2, 4, {}, 1].sort() -> [1, 2, 4, 5, {}]

标签: javascript arrays sorting


【解决方案1】:

当谈到Array.sort 的实现时,您还必须问哪个引擎?它们在如何最终获得数组的最终sorted 版本方面并不完全相同。例如V8在进行any排序之前有一个预处理和后处理步骤:

V8 在实际对任何内容进行排序之前有一个预处理步骤,并且 也是一个后处理步骤。基本思想是收集所有 将非未定义值放入临时列表中,对该临时列表进行排序 然后将排序后的值写回实际的数组或对象。 这使 V8 无需关心与访问器或 排序过程中的原型链。

你可以找到V8经过here整个过程的相当详细的解释

V8 排序的实际源代码(使用Timsort)可以是found here,现在使用Torque 语言。

V8的js测试Array.sort可以是seen here

然而,底线是实际上没有从原始数组中删除任何内容,因为它不应该被删除。排序不应该对mutate 原始数组。如果你打电话给myArray.sort(),那将是超级weird,突然之间它的8个元素中减少了5个元素(例如)。这不是您在任何Array.sort 规范中都能找到的东西。

Array.sort 也密切关注它对它们进行排序和排序的类型。示例:

let arr = [4,2,5,,,,3,false,{},undefined,null,0,function(){},[]]

console.log(arr.sort())

请注意,在上面的输出中,首先是 array,然后是 numeric 值、object literalBooleanfunctionnull,然后是 undefined/empty。因此,如果您想真正匹配规范,则必须考虑不同类型的排序方式。

【讨论】:

  • 非常感谢您分享这些链接。我天真地以为源代码会在js中。 V8 文章显示的排序过程,我可以看到我的非常不同。 V8 对未定义的数组进行排序,然后将它们分配给原始数组,而我的则相反。 V8 使用 timsort,而我使用归并排序(自下而上)。幸运的是,我的排序还输出了具有不同数据类型示例的数组的相同顺序。
猜你喜欢
  • 1970-01-01
  • 2011-03-14
  • 2015-06-18
  • 2016-01-15
  • 2011-02-08
  • 2015-05-12
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
相关资源
最近更新 更多