使用JavaScript排序数组减少功能

Ame*_*icA 21 javascript sorting algorithm reduce

我经常研究一些JavaScript面试问题,突然间我看到一个关于使用reduce函数进行排序的问题Array,我在MDN中读到了它并在一些medium文章中使用它,但排序Array是如此创新:

const arr = [91,4,6,24,8,7,59,3,13,0,11,98,54,23,52,87,4];
Run Code Online (Sandbox Code Playgroud)

我想了很多,但我不知道如何回答这个问题,这个reduce call back功能一定是怎么回事?是什么initialValuereduce功能?什么是accumulatorcurrentValuecall back功能reduce

最后,这种方式是否比其他排序算法有一些好处?或者改进其他算法是否有用?

Jon*_*lms 21

在这里使用reduce是没有意义的,但是你可以使用一个新数组作为累加器并对所有元素进行插入排序:

array.reduce((sorted, el) => {
  let index = 0;
  while(index < array.length && el < array[index]) index++;
  sorted.splice(index, 0, el);
  return sorted;
}, []);
Run Code Online (Sandbox Code Playgroud)

这是没有 reduce 的版本:

array.sort((a, b) => a - b);
Run Code Online (Sandbox Code Playgroud)

现在有一些写减速器的一般技巧:

如何减少回叫功能?

你要么采用累加器方法,那么reducer应该根据当前元素对累加器应用修改并返回它:

(acc, el) => acc
Run Code Online (Sandbox Code Playgroud)

或者如果累加器和元素具有理智类型并且在逻辑上相等,则不需要区分它们:

 (a, b) => a + b
Run Code Online (Sandbox Code Playgroud)

reduce函数的initialValue是什么?

您应该问自己"当应用于空阵列时,应该减少什么?"

现在最重要的是:何时使用减少?(IMO)

如果要将数组的值归结为单个值或对象.


Lex*_*Lex 8

Array.sort改变使用Array.reduce鼓励纯函数的数组.您可以在排序之前克隆数组.

我相信这个问题旨在通过强制执行约束来让您以不同的方式思考.它会测试你对reduce工作原理的了解,并且答案显示有许多方法可以给猫皮肤.它将展示你解决这个问题的个人风格.

我选择使用Array.findIndexArray.splice.

const sortingReducer = (accumulator, value) => {
  const nextIndex = accumulator.findIndex(i => value < i );
  const index = nextIndex > -1 ? nextIndex : accumulator.length;
  accumulator.splice(index, 0, value);
  return accumulator;
}

const input = [5,4,9,1];
const output = input.reduce(sortingReducer, []);
Run Code Online (Sandbox Code Playgroud)

使用样本输入进行测试

arr.reduce(sortingReducer, [])
// (17) [0, 3, 4, 4, 6, 7, 8, 11, 13, 23, 24, 52, 54, 59, 87, 91, 98]
Run Code Online (Sandbox Code Playgroud)


Jol*_*ker 5

这是Jonas W插入排序解决方案的(imo)更优雅的版本。回调只是构建一个包含所有较低值、新值和所有较高值的​​新数组。避免使用显式循环或索引,因此更容易一眼看出它是否正常工作。

const insertValue = (arr, value) =>
  [...arr.filter(n => n <= value), value, ...arr.filter(n => n > value)]

const testArr = [91, 4, 6, 24, 8, 7, 59, 3, 13, 0, 11, 98, 54, 23, 52, 87, 4]

console.log(testArr.reduce(insertValue, []))
Run Code Online (Sandbox Code Playgroud)

  • 可能的问题:数组中的任何“NaN”条目都将被删除,因为“NaN”既不是“&lt;= value”也不是“&gt; value”。显然,OP 的示例中没有“NaN”,而是一个特殊情况,只是指出它。 (2认同)