JavaScript中快速稳定的排序算法实现


103

我正在寻找一个大约200-300个对象的数组,按特定的键和给定的顺序(asc / desc)进行排序。结果的顺序必须一致且稳定。

最好使用哪种算法,您能否提供一个用javascript实现的示例?

谢谢!


5
由于至少Chrome的数组排序似乎不稳定,因此不建议您依赖内置数组排序。
Nosredna

总结一下:由于现代浏览器之间Array.sort的稳定性不一致,我进行了手动合并排序(主要是chrome在本文发表时未实现稳定的排序)。谢谢大家的帮助!
威廉·卡萨林

“稳定”排序是什么意思?
mowwwalker 2013年

2
@mowwwalker稳定排序是一种排序方式,其中所有具有相同排序值的项目都按照与原始集合中相同的顺序保留。en.wikipedia.org/wiki/Sorting_algorithm#稳定度
Kornelije Petak 2014年

要回答“使用哪种最佳算法”,我们需要知道您的数据是否存在任何底层结构。以下许多答案只是谈论使用合并排序或快速排序,实际上,这取决于数据。仅仅回答我不会说不是一个简单的问题。谷歌一些排序算法,并阅读它们,以了解我的意思。TimSortRadix Sort是我推荐阅读的两个很好的例子。

Answers:


113

可以从不稳定的排序函数中获得稳定的排序。

在排序之前,您需要确定所有元素的位置。在您的排序条件下,如果两个元素相等,那么您将按位置排序。

多田 您的排序很稳定。

如果您想进一步了解这项技术及其实现方法,我已经在博客上写了一篇文章:http : //blog.vjeux.com/2010/javascript/javascript-sorting-table.html


32
您能否在这里提供答案,而不是发布并链接到您的博客!谢谢
Mohammad Kermani 16/12/11

4
欢迎使用指向解决方案的链接,但是请确保没有该链接的情况下,您的回答是有用的:在链接周围添加上下文,以便您的其他用户可以了解它的含义和含义,然后引用您所使用页面中最相关的部分如果目标页面不可用,请重新链接。只是链接的答案可能会被删除。
塞缪尔·柳

@Vjeux既然已经越来越流行了,您介意将相关代码粘贴到此答案中吗?这会很有帮助!谢谢!
威廉·卡萨琳

34

由于您正在寻找稳定的东西,因此合并排序应该可以。

http://www.stoimen.com/blog/2010/07/02/friday-algorithms-javascript-merge-sort/

可以在上面的网站上找到该代码:

function mergeSort(arr)
{
    if (arr.length < 2)
        return arr;

    var middle = parseInt(arr.length / 2);
    var left   = arr.slice(0, middle);
    var right  = arr.slice(middle, arr.length);

    return merge(mergeSort(left), mergeSort(right));
}

function merge(left, right)
{
    var result = [];

    while (left.length && right.length) {
        if (left[0] <= right[0]) {
            result.push(left.shift());
        } else {
            result.push(right.shift());
        }
    }

    while (left.length)
        result.push(left.shift());

    while (right.length)
        result.push(right.shift());

    return result;
}

编辑:

根据这篇文章,它看起来像Array.Sort在某些实现中使用合并排序。


++合并排序是我的最爱。它简单而稳定,没有最坏的情况。
Mike Dunlavey

该网站的链接关闭了:(
ahitt6345 '16

为该示例找到了一个新网站。
kemiller2002 '02

7
注意:Array#shift可能在O(n)时间工作,所以您merge在O(n * n)时间工作。
4esn0k '16

22

使用ES2017功能(如箭头功能和解构)的同一事物的简短版本:

功能

var stableSort = (arr, compare) => arr
  .map((item, index) => ({item, index}))
  .sort((a, b) => compare(a.item, b.item) || a.index - b.index)
  .map(({item}) => item)

它接受输入数组和比较功能:

stableSort([5,6,3,2,1], (a, b) => a - b)

它还返回新数组,而不是像内置Array.sort()一样进行就地排序函数。

测试

如果采用以下input数组,则最初按以下顺序排序weight

// sorted by weight
var input = [
  { height: 100, weight: 80 },
  { height: 90, weight: 90 },
  { height: 70, weight: 95 },
  { height: 100, weight: 100 },
  { height: 80, weight: 110 },
  { height: 110, weight: 115 },
  { height: 100, weight: 120 },
  { height: 70, weight: 125 },
  { height: 70, weight: 130 },
  { height: 100, weight: 135 },
  { height: 75, weight: 140 },
  { height: 70, weight: 140 }
]

然后height使用stableSort以下命令对其进行排序:

stableSort(input, (a, b) => a.height - b.height)

结果是:

// Items with the same height are still sorted by weight 
// which means they preserved their relative order.
var stable = [
  { height: 70, weight: 95 },
  { height: 70, weight: 125 },
  { height: 70, weight: 130 },
  { height: 70, weight: 140 },
  { height: 75, weight: 140 },
  { height: 80, weight: 110 },
  { height: 90, weight: 90 },
  { height: 100, weight: 80 },
  { height: 100, weight: 100 },
  { height: 100, weight: 120 },
  { height: 100, weight: 135 },
  { height: 110, weight: 115 }
]

但是,input使用内置功能Array.sort()(在Chrome / NodeJS中)对同一数组进行排序:

input.sort((a, b) => a.height - b.height)

返回值:

var unstable = [
  { height: 70, weight: 140 },
  { height: 70, weight: 95 },
  { height: 70, weight: 125 },
  { height: 70, weight: 130 },
  { height: 75, weight: 140 },
  { height: 80, weight: 110 },
  { height: 90, weight: 90 },
  { height: 100, weight: 100 },
  { height: 100, weight: 80 },
  { height: 100, weight: 135 },
  { height: 100, weight: 120 },
  { height: 110, weight: 115 }
]

资源资源

更新资料

Array.prototype.sort 现在在V8 v7.0 / Chrome 70中稳定!

以前,V8对包含10个以上元素的数组使用不稳定的QuickSort。现在,我们使用稳定的TimSort算法。

资源


1
stableSort功能是一个非常好的解决方案!
lhermann

16

我知道这个问题已经回答了一段时间,但是我碰巧在剪贴板中对Array和jQuery有一个很好的稳定合并排序实现,因此我将与大家分享,希望以后的搜索者会发现它有用。

它允许您像常规Array.sort实现一样指定自己的比较功能。

实作

// Add stable merge sort to Array and jQuery prototypes
// Note: We wrap it in a closure so it doesn't pollute the global
//       namespace, but we don't put it in $(document).ready, since it's
//       not dependent on the DOM
(function() {

  // expose to Array and jQuery
  Array.prototype.mergeSort = jQuery.fn.mergeSort = mergeSort;

  function mergeSort(compare) {

    var length = this.length,
        middle = Math.floor(length / 2);

    if (!compare) {
      compare = function(left, right) {
        if (left < right)
          return -1;
        if (left == right)
          return 0;
        else
          return 1;
      };
    }

    if (length < 2)
      return this;

    return merge(
      this.slice(0, middle).mergeSort(compare),
      this.slice(middle, length).mergeSort(compare),
      compare
    );
  }

  function merge(left, right, compare) {

    var result = [];

    while (left.length > 0 || right.length > 0) {
      if (left.length > 0 && right.length > 0) {
        if (compare(left[0], right[0]) <= 0) {
          result.push(left[0]);
          left = left.slice(1);
        }
        else {
          result.push(right[0]);
          right = right.slice(1);
        }
      }
      else if (left.length > 0) {
        result.push(left[0]);
        left = left.slice(1);
      }
      else if (right.length > 0) {
        result.push(right[0]);
        right = right.slice(1);
      }
    }
    return result;
  }
})();

用法示例

var sorted = [
  'Finger',
  'Sandwich',
  'sandwich',
  '5 pork rinds',
  'a guy named Steve',
  'some noodles',
  'mops and brooms',
  'Potato Chip Brand® chips'
].mergeSort(function(left, right) {
  lval = left.toLowerCase();
  rval = right.toLowerCase();

  console.log(lval, rval);
  if (lval < rval)
    return -1;
  else if (lval == rval)
    return 0;
  else
    return 1;
});

sorted == ["5 pork rinds", "a guy named Steve", "Finger", "mops and brooms", "Potato Chip Brand® chips", "Sandwich", "sandwich", "some noodles"];

4
请注意,这是在与本地排序,其工作机会地方,这意味着这不能仅仅是在下降了。
埃里克

3
也许稳定,但是此方法比本地方法慢20倍array.sort,请参阅此处的字符串和整数测试-> jsfiddle.net/QC64j
davidkonrad

2
当然,它比本机排序慢-它不是本机。这不可能。也确实没有进行就地排序。这也是不可能的(最好的情况是创建副本然后覆盖原始副本)。此外,尽管JavaScript本身具有本机排序行为,但返回排序后的副本更像是JavaScript。该函数也称为,mergeSort而不是sort,因此不打算作为替代。有时,您只需要稳定的合并排序,例如,按列对表进行排序时。
贾斯汀力

1
错误,Node的本机排序是用javascript编写的。用javascript编程的算法完全有可能超越本机排序。我完全在javascript(一种自适应合并排序类型)中构建了一种排序算法,该算法可以实现Kremes / creams / Kreams node中的本机quicksort。此注释的目的是表明,对于javascript,native无关紧要,因为排序算法是用javascript编写的,而不是用某些高级语言(例如c ++)编写的。证明在这里:github.com/nodejs/node/blob/master/deps/v8/src/js/array.js
ahitt6345 '16

2
对于任何想要比该实现要快得多的就地插入解决方案的人,请查看我的答案
Patrick Roberts

10

基于此答案中的断言,您可以使用以下polyfill来实现稳定的排序,而不考虑本机实现:

// ECMAScript 5 polyfill
Object.defineProperty(Array.prototype, 'stableSort', {
  configurable: true,
  writable: true,
  value: function stableSort (compareFunction) {
    'use strict'

    var length = this.length
    var entries = Array(length)
    var index

    // wrap values with initial indices
    for (index = 0; index < length; index++) {
      entries[index] = [index, this[index]]
    }

    // sort with fallback based on initial indices
    entries.sort(function (a, b) {
      var comparison = Number(this(a[1], b[1]))
      return comparison || a[0] - b[0]
    }.bind(compareFunction))

    // re-map original array to stable sorted values
    for (index = 0; index < length; index++) {
      this[index] = entries[index][1]
    }
    
    return this
  }
})

// usage
const array = Array(500000).fill().map(() => Number(Math.random().toFixed(4)))

const alwaysEqual = () => 0
const isUnmoved = (value, index) => value === array[index]

// not guaranteed to be stable
console.log('sort() stable?', array
  .slice()
  .sort(alwaysEqual)
  .every(isUnmoved)
)
// guaranteed to be stable
console.log('stableSort() stable?', array
  .slice()
  .stableSort(alwaysEqual)
  .every(isUnmoved)
)

// performance using realistic scenario with unsorted big data
function time(arrayCopy, algorithm, compare) {
  var start
  var stop
  
  start = performance.now()
  algorithm.call(arrayCopy, compare)
  stop = performance.now()
  
  return stop - start
}

const ascending = (a, b) => a - b

const msSort = time(array.slice(), Array.prototype.sort, ascending)
const msStableSort = time(array.slice(), Array.prototype.stableSort, ascending)

console.log('sort()', msSort.toFixed(3), 'ms')
console.log('stableSort()', msStableSort.toFixed(3), 'ms')
console.log('sort() / stableSort()', (100 * msSort / msStableSort).toFixed(3) + '%')

运行上面执行的性能测试,stableSort()似乎可以运行sort()59-61版Chrome 的速度的57%。

.bind(compareFunction)在包装的匿名函数中使用,通过将每个调用分配给上下文来stableSort()避免不必要的作用域引用,从而使相对性能从38%左右提高了compareFunction

更新资料

将三元运算符更改为逻辑短路,这通常会平均表现更好(效率相差2-3%)。


5

下面的代码通过应用提供的比较函数对提供的数组进行排序,当比较函数返回0时返回原始索引比较:

function stableSort(arr, compare) {
    var original = arr.slice(0);

    arr.sort(function(a, b){
        var result = compare(a, b);
        return result === 0 ? original.indexOf(a) - original.indexOf(b) : result;
    });

    return arr;
}

下面的示例按姓氏对名称数组进行排序,保留姓氏相等的顺序:

var names = [
	{ surname: "Williams", firstname: "Mary" },
	{ surname: "Doe", firstname: "Mary" }, 
	{ surname: "Johnson", firstname: "Alan" }, 
	{ surname: "Doe", firstname: "John" }, 
	{ surname: "White", firstname: "John" }, 
	{ surname: "Doe", firstname: "Sam" }
]

function stableSort(arr, compare) {
    var original = arr.slice(0);

    arr.sort(function(a, b){
        var result = compare(a, b);
        return result === 0 ? original.indexOf(a) - original.indexOf(b) : result;
    });
	
    return arr;
}

stableSort(names, function(a, b) { 
	return a.surname > b.surname ? 1 : a.surname < b.surname ? -1 : 0;
})

names.forEach(function(name) {
	console.log(name.surname + ', ' + name.firstname);
});


对于基本类型或数组中的重复元素不稳定。 jQuery.expando.split( "" ).sort( ( a, b ) => 0 ).join( "" ) === jQuery.expando
火星

3

这是一个稳定的实现。它通过使用本机排序来工作,但是在元素比较相等的情况下,可以使用原始索引位置来打破联系。

function stableSort(arr, cmpFunc) {
    //wrap the arr elements in wrapper objects, so we can associate them with their origional starting index position
    var arrOfWrapper = arr.map(function(elem, idx){
        return {elem: elem, idx: idx};
    });

    //sort the wrappers, breaking sorting ties by using their elements orig index position
    arrOfWrapper.sort(function(wrapperA, wrapperB){
        var cmpDiff = cmpFunc(wrapperA.elem, wrapperB.elem);
        return cmpDiff === 0 
             ? wrapperA.idx - wrapperB.idx
             : cmpDiff;
    });

    //unwrap and return the elements
    return arrOfWrapper.map(function(wrapper){
        return wrapper.elem;
    });
}

非彻底的测试

var res = stableSort([{a:1, b:4}, {a:1, b:5}], function(a, b){
    return a.a - b.a;
});
console.log(res);

另一个暗示这个问题的答案,但是没有发布Codez。

但是,按照我的基准,它并不快。我修改了合并排序隐式以接受自定义比较器功能,并且速度更快。


您的基准测试正确吗?看来,你的“stableSort”不修改输入数组,其他种类-在“设置”做的,因为你没有重现“ARR”,其他类型的排序已经排序阵列....
4esn0k

@ 4esn0k您读错了吗?我说我的stableSort函数不是很快。
山羊

@gota,啊,原谅我
4esn0k

3

您也可以使用Timsort。这是一个非常复杂的算法(超过400行,因此这里没有源代码),因此请参阅Wikipedia的描述或使用现有的JavaScript实现之一:

GPL 3实施。打包为Array.prototype.timsort。似乎是Java代码的完全重写。

公共领域的实现作为教程,示例代码仅显示其与整数的使用。

Timsort是mergesort和shuffle排序的高度优化的混合,并且是Python和Java(1.7+)中的默认排序算法。这是一种复杂的算法,因为在许多特殊情况下它使用不同的算法。但结果是,它在各种情况下都非常快。


1

来自http://www.stoimen.com/blog/2010/07/02/friday-algorithms-javascript-merge-sort/的一个简单的mergeSort

var a = [34, 203, 3, 746, 200, 984, 198, 764, 9];

function mergeSort(arr)
{
    if (arr.length < 2)
         return arr;

    var middle = parseInt(arr.length / 2);
    var left   = arr.slice(0, middle);
    var right  = arr.slice(middle, arr.length);

    return merge(mergeSort(left), mergeSort(right));
}

function merge(left, right)
{
     var result = [];

    while (left.length && right.length) {
         if (left[0] <= right[0]) {
             result.push(left.shift());
         } else {
            result.push(right.shift());
         }
    }

    while (left.length)
        result.push(left.shift());

    while (right.length)
        result.push(right.shift());

    return result;
}

console.log(mergeSort(a));

0

我必须按任意列对多维数组进行排序,然后再对它进行排序。我使用此函数进行排序:

function sortMDArrayByColumn(ary, sortColumn){

    //Adds a sequential number to each row of the array
    //This is the part that adds stability to the sort
    for(var x=0; x<ary.length; x++){ary[x].index = x;}

    ary.sort(function(a,b){
        if(a[sortColumn]>b[sortColumn]){return 1;}
        if(a[sortColumn]<b[sortColumn]){return -1;}
        if(a.index>b.index){
            return 1;
        }
        return -1;
    });
}

请注意,ary.sort永远不会返回零,这是“ sort”函数的某些实现在其中做出可能不正确的决定的地方。

这也非常快。


0

这是使用MERGE SORT的原型方法扩展JS默认Array对象的方法。此方法允许对特定键(第一个参数)和给定顺序(“ asc” /“ desc”作为第二个参数)进行排序

Array.prototype.mergeSort = function(sortKey, direction){
  var unsortedArray = this;
  if(unsortedArray.length < 2) return unsortedArray;

  var middle = Math.floor(unsortedArray.length/2);
  var leftSubArray = unsortedArray.slice(0,middle).mergeSort(sortKey, direction);
  var rightSubArray = unsortedArray.slice(middle).mergeSort(sortKey, direction);

  var sortedArray = merge(leftSubArray, rightSubArray);
  return sortedArray;

  function merge(left, right) {
    var combined = [];
    while(left.length>0 && right.length>0){
      var leftValue = (sortKey ? left[0][sortKey] : left[0]);
      var rightValue = (sortKey ? right[0][sortKey] : right[0]);
      combined.push((direction === 'desc' ? leftValue > rightValue : leftValue < rightValue) ? left.shift() : right.shift())
    }
    return combined.concat(left.length ? left : right)
  }
}

您可以通过将上述代码段放入浏览器控制台中来自己进行测试,然后尝试:

var x = [2,76,23,545,67,-9,12];
x.mergeSort(); //[-9, 2, 12, 23, 67, 76, 545]
x.mergeSort(undefined, 'desc'); //[545, 76, 67, 23, 12, 2, -9]

或基于对象数组中的特定字段进行排序:

var y = [
  {startTime: 100, value: 'cat'},
  {startTime: 5, value: 'dog'},
  {startTime: 23, value: 'fish'},
  {startTime: 288, value: 'pikachu'}
]
y.mergeSort('startTime');
y.mergeSort('startTime', 'desc');

0

因此,我需要为我的React + Redux应用程序提供稳定的排序,而Vjeux的回答对我有所帮助。但是,我的(通用)解决方案似乎与到目前为止在这里看到的其他解决方案不同,因此,如果其他人有匹配的用例,我将共享它:

  • 我真的只想拥有与sort()API 类似的东西,可以在其中传递比较器函数。
  • 有时我可以就地排序,有时我的数据是不可变的(因为Redux),我需要排序的副本。所以我需要针对每个用例的稳定排序功能。
  • ES2015。

我的解决方案是创建一个类型数组indices,然后使用比较函数根据要排序的数组对这些索引进行排序。然后,我们可以使用sorted indices对原始数组进行排序,也可以单遍创建排序后的副本。如果这令人困惑,请这样考虑:通常在哪里传递比较函数,例如:

(a, b) => { 
  /* some way to compare a and b, returning -1, 0, or 1 */ 
};

您现在改为使用:

(i, j) => { 
  let a = arrayToBeSorted[i], b = arrayToBeSorted[j]; 
  /* some way to compare a and b, returning -1 or 1 */
  return i - j; // fallback when a == b
}

速度不错;它基本上是内置的排序算法,最后加上两次线性遍历,以及一层额外的指针间接开销。

很高兴收到有关此方法的反馈。这是它的完整实现:

/**
 * - `array`: array to be sorted
 * - `comparator`: closure that expects indices `i` and `j`, and then
 *   compares `array[i]` to `array[j]` in some way. To force stability,
 *   end with `i - j` as the last "comparison".
 * 
 * Example:
 * ```
 *  let array = [{n: 1, s: "b"}, {n: 1, s: "a"}, {n:0, s: "a"}];
 *  const comparator = (i, j) => {
 *    const ni = array[i].n, nj = array[j].n;
 *    return ni < nj ? -1 :
 *      ni > nj ? 1 :
 *        i - j;
 *  };
 *  stableSortInPlace(array, comparator);
 *  // ==> [{n:0, s: "a"}, {n:1, s: "b"}, {n:1, s: "a"}]
 * ```
 */
function stableSortInPlace(array, comparator) {
  return sortFromIndices(array, findIndices(array, comparator));
}

function stableSortedCopy(array, comparator){
  let indices = findIndices(array, comparator);
  let sortedArray = [];
  for (let i = 0; i < array.length; i++){
    sortedArray.push(array[indices[i]]);
  }
  return sortedArray;
}

function findIndices(array, comparator){
  // Assumes we don't have to worry about sorting more than 
  // 4 billion elements; if you know the upper bounds of your
  // input you could replace it with a smaller typed array
  let indices = new Uint32Array(array.length);
  for (let i = 0; i < indices.length; i++) {
    indices[i] = i;
  }
  // after sorting, `indices[i]` gives the index from where
  // `array[i]` should take the value from, so to sort
  // move the value at at `array[indices[i]]` to `array[i]`
  return indices.sort(comparator);
}

// If I'm not mistaken this is O(2n) - each value is moved
// only once (not counting the vacancy temporaries), and 
// we also walk through the whole array once more to check
// for each cycle.
function sortFromIndices(array, indices) {
  // there might be multiple cycles, so we must
  // walk through the whole array to check.
  for (let k = 0; k < array.length; k++) {
    // advance until we find a value in
    // the "wrong" position
    if (k !== indices[k]) {
      // create vacancy to use "half-swaps" trick,
      // props to Andrei Alexandrescu
      let v0 = array[k];
      let i = k;
      let j = indices[k];
      while (j !== k) {
        // half-swap next value
        array[i] = array[j];
        // array[i] now contains the value it should have,
        // so we update indices[i] to reflect this
        indices[i] = i;
        // go to next index
        i = j;
        j = indices[j];
      }
      // put original array[k] back in
      // and update indices
      array[i] = v0;
      indices[i] = i;
    }
  }
  return array;
}

0

我知道这已经得到了足够的答复。我只是想为任何登陆这里寻求帮助的人发布一个快速的TS实施。

export function stableSort<T>( array: T[], compareFn: ( a: T, b: T ) => number ): T[] {
    const indices = array.map( ( x: T, i: number ) => ( { element: x, index: i } ) );

    return indices.sort( ( a, b ) => {
        const order = compareFn( a.element, b.element );
        return order === 0 ? a.index - b.index : order;
    } ).map( x => x.element );
}

该方法不再像本地排序那样就地运行。我还想指出,这不是最有效的。它添加了两个O(n)阶的循环。尽管排序本身很可能是O(n log(n)),所以它小于O。

提到的一些解决方案性能更高,以为这可能是更少的代码,也使用internal Array.prototype.sort

(对于Javascript解决方案,只需删除所有类型)


0

根据v8开发者博客caniuse.com Array.sort已经按照现代浏览器中的规范要求保持稳定,因此您无需推出自己的解决方案。我能看到的唯一例外是Edge,它应该很快移到铬上并也支持它。


0

function sort(data){
    var result=[];
    var array = data;
    const array2=data;
    const len=array2.length;
    for(var i=0;i<=len-1;i++){
    var min = Math.min.apply(Math,array)
    result.push(min);
    var index=array.indexOf(min)
    array.splice(index,1);
    }
    return result;
}   
sort([9,8,5,7,9,3,9,243,4,5,6,3,4,2,4,7,4,9,55,66,33,66]);


-1

计数排序比合并排序快(它的执行时间为O(n)),并且打算用于整数。

Math.counting_sort = function (m) {
    var i
    var j
    var k
    var step
    var start
    var Output
    var hash
    k = m.length
    Output = new Array ()
    hash = new Array ()
    // start at lowest possible value of m
    start = 0
    step = 1
    // hash all values
    i = 0
    while ( i < k ) {
        var _m = m[i]
        hash [_m] = _m
        i = i + 1
    }
    i = 0
    j = start
    // find all elements within x
    while ( i < k ) {
        while ( j != hash[j] ) {
            j = j + step
        }
        Output [i] = j
        i = i + 1
        j = j + step
    }
    return Output
}

例:

var uArray = new Array ()<br/>
var sArray = new Array ()<br/><br/>
uArray = [ 10,1,9,2,8,3,7,4,6,5 ]<br/>
sArray = Math.counting_sort ( uArray ) // returns a sorted array

12
有几点要说:1.计数排序仅在密集的数字空间中才能很好地工作。(尝试对数组[1,2e9,1e9]进行排序)。2.不要像while循环那样编写for循环。3.不要将任何东西随机添加到Math名称空间中。4.您可能要考虑与分号交朋友。
2014年

另外,如果数组具有重复值,它将永远运行。例如,将array [3, 1, 3]哈希到[undefined, 1, undefined, 3]。我们得到两个非未定义的值,而算法期望其中三个。
MKPS '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.