删除阵列上的相邻重复项

时间:2019-02-09 05:10:20

标签: javascript arrays recursion

假设我们有一个数字数组,类似于下一个:

const input = [2, 2, 0, 2, 3, 3, 0, 0, 1, 1];

目标是删除重复的值,但前提是它们是相邻的。因此,先前样本的预期输出应为:

[2, 0, 2, 3, 0, 1]

到目前为止,我设法使用递归方法几乎解决了这个问题,但是由于某种原因,我无法确定生成的结果没有返回(但是,您可以在返回条件之前在控制台日志上看到它) )。

const input = [2, 2, 0, 2, 3, 3, 0, 0, 1, 1];

const remAdjDups = (arr, output = []) =>
{
    if (!arr.length)
    {
        console.log("Result before return: ", output);
        return output;
    }

    if (arr[0] === arr[1])
    {
        arr.splice(1, 1);
        remAdjDups(arr, output);
    }
    else
    {
        remAdjDups(arr.slice(1), output.concat(arr[0]));
    }
}

let out = remAdjDups(input.slice());
console.log("output: ", out);

因此,首先也是主要,我想了解我的方法正在发生的事情,而第二我愿意接受任何其他类型的方法可以解决这个问题。


更新的解决方案

以防万一有人感兴趣,我终于以这种方式使用递归解决了这个问题。我知道过滤器解决方案简短而优雅,但是我正在通过递归训练解决方案。

const input = [2, 2, 0, 2, 3, 3, 0, 0, 1, 1, 1, 1, 1];

const remAdjDups = ([x, y, ...rest], out = []) =>
{
    if (!rest.length)
        return (x === y) ? [...out, x] : [...out, x, y];
    else if (x === y)
        return remAdjDups([x, ...rest], out);
    else
        return remAdjDups([y, ...rest], [...out, x]);
}

let out = remAdjDups(input.slice());
console.log("output: ", out);

5 个答案:

答案 0 :(得分:3)

关于您的解决方案,只需在return之前添加remAdjDups(arr...

P.S。

我为此使用了Array.prototype.filter

const input = [2, 2, 0, 2, 3, 3, 0, 0, 1, 1];

const result = input.filter((i,idx) => input[idx-1] !== i)

console.log(result)

答案 1 :(得分:1)

您可以使用filter

const input = [2, 2, 0, 2, 3, 3, 0, 0, 1, 1];

const result = input.filter((i,index) => {
 if(index != 0){
  return input[index-1] !== i
 } 
 return i
})

console.log(result)

答案 2 :(得分:1)

您的方法是正确的,您只是忘记了return调用的结果recursive。您只需要添加return语句即可。

const input = [2, 2, 0, 2, 3, 3, 0, 0, 1, 1];

const remAdjDups = (arr, output = []) =>
{
    if (!arr.length)
    {
        console.log("Result before return: ", output);
        return output;
    }

    if (arr[0] === arr[1])
    {
        arr.splice(1, 1);
        return remAdjDups(arr, output);
    }
    else
    {
        return remAdjDups(arr.slice(1), output.concat(arr[0]));
    }
}

let out = remAdjDups(input.slice());
console.log("output: ", out);

希望这会有所帮助!

答案 3 :(得分:1)

您需要在代码的returnif块中使用else,否则将返回undefined

if (arr[0] === arr[1])
{
    arr.splice(1, 1);
    return remAdjDups(arr, output);
}
else
{
    return remAdjDups(arr.slice(1), output.concat(arr[0]));
}

这是使用Array#reduce

的另一种方法

const input = [2, 2, 0, 2, 3, 3, 0, 0, 1, 1, 1, 1, 6, 3, 3, 5, 8, 8, 0, -1, -1, 2, 56, 57, 56];

const arr = input.reduce((acc, ele, idx) => {
  if(ele !== input[idx + 1]){
   acc.push(ele)
  }
  return acc;
}, []);

console.log(arr);

答案 4 :(得分:1)

通过数学归纳法递归可以很好地解决此问题-

  1. 如果第一个元素a为空,则返回空结果
  2. (归纳)第一个元素不为null。如果第二个元素b为空,则返回第一个元素a
  3. 的单例数组
  4. (归纳)第一个元素或第二个元素都不为空。如果a等于b,则返回删除了a的递归结果
  5. (归纳)第一个元素和第二个元素都不为空,并且彼此不相等。返回递归结果而不删除ab

const removeDupes = ([ a, b, ...more ]) =>
  a == null
    ? []                                  // 1
: b == null
    ? [ a ]                               // 2
: a === b
    ? removeDupes([ b, ...more ])         // 3
: [ a, ...removeDupes([ b, ...more ]) ]   // 4

const input =
  [2, 2, 0, 2, 3, 3, 3, 0, 0, 1, 1];

const result =
  removeDupes(input)
  
console.log(result)
// [ 2, 0, 2, 3, 0, 1 ]