用递归函数重新排序

时间:2019-06-13 04:30:47

标签: javascript recursion

如何使用递归函数对先有偶数索引然后有奇数索引的数组重新排序? 例如: 输入:[5、2、4、9] 输出:[5,4,2,9]

我想改进这段代码。

let arrayB = [],
  arrayOdd = [],
  arrayEven = [];
let i = 0;

const reorder = (arrayA) => {
  if (arrayA.length >= 2) {
    if (i < arrayA.length) {
      i === 0 || i % 2 === 0 ? arrayEven.push(arrayA[i]) : arrayOdd.push(arrayA[i]);
      i++;
      arrayB = [...arrayEven, ...arrayOdd];
      reorder(arrayA);
    } else {
      arrayOdd = [];
      arrayEven = [];
      i = 0;
    }
    return arrayB;
  }
}

console.log(reorder([4, 8, 12, 16]));

console.log(reorder([1, 2, 3, 4, 5, 6, 7, 8, 9]));

4 个答案:

答案 0 :(得分:2)

不知道为什么需要递归函数。应该这样做:

const reorder = (a) => [...a.filter((_, i) => !(i % 2)), ...a.filter((_, i) => i % 2)];

console.log(reorder([4, 8, 12, 16]));
console.log(reorder([1, 2, 3, 4, 5, 6, 7, 8, 9]));


由于您在注释中规定您有使用最小空间要求的递归函数的说明,因此以下解决方案使用Array.prototype.splice()来修改数组:

const reorder = (a, offset = 2) => {
  if (offset < a.length) {
    a.splice(offset / 2, 0, ...a.splice(offset, 1));
    return reorder(a, offset + 2);
  }
  return a;
};

console.log(reorder([4, 8, 12, 16]));
console.log(reorder([1, 2, 3, 4, 5, 6, 7, 8, 9]));

请注意,与Array.prototype.sort()函数一样,以上函数仅出于方便而返回数组。没有创建新的数组。

答案 1 :(得分:1)

我认为您可以通过使用数组的排序方法来做到这一点。但是为此,您可能需要使用map获取索引,然后再转换回值。

const isOdd = n => n % 2 === 1;
const reorder = input => input.map((value, index) => ({index, value})).sort((a,b) => 
    isOdd(a.index) ? 1 : isOdd(b.index) ? -1 : 0).map(({value}) => value);

console.log(reorder([4, 8, 12, 16]));

console.log(reorder([1, 2, 3, 4, 5, 6, 7, 8, 9]));

答案 2 :(得分:0)

避免使用全局变量。

const reorder = (arrayA, arrayOdd = [], arrayEven = []) => {
    if (arrayA.length >= 1)
        arrayEven.push(arrayA.shift());
    if (arrayA.length >= 1) {
        arrayOdd.push(arrayA.shift());	  
        reorder(arrayA, arrayOdd, arrayEven);    
    }
    return [...arrayEven, ...arrayOdd];
}

console.log(reorder([4, 8, 12, 16]));
  
console.log(reorder([1, 2, 3, 4, 5, 6, 7, 8, 9]));

答案 3 :(得分:0)

我不知道您为什么选择递归执行此操作,但这似乎可以做到:

const evenThenOdd = ([e = undefined, o = undefined, ...xs], evens = [], odds = []) => 
  e == undefined
    ? [...evens, ...odds]
    : o == undefined 
      ? evenThenOdd ( xs, [...evens, e] [odds] )
      : evenThenOdd ( xs, [...evens, e], [...odds, o] )


console .log (
  evenThenOdd ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
  //~> [0, 2, 4, 6, 8, 1, 3, 5, 7, 9]
)

我们保留evensodds值数组。当数组中什么都没有时,基本情况就是将这两个数组串联起来。其他两种情况是当剩下一项时,又剩下两项以上。如果undefined值是您要处理的数组的合法元素,请添加const None = Symbol(),然后将每个undefined替换为None


一个更干净,非递归的解决方案可能看起来像这样:

const evenThenOdd = (xs) => [
  ...xs.filter((_, i) => i % 2 == 0),
  ...xs.filter((_, i) => i % 2 == 1),
]