JavaScript:请参阅reduce方法中的剩余数组(折叠)?

时间:2017-11-19 23:25:27

标签: javascript functional-programming fold

我想测试一个数组只包含唯一元素,我的解决方案如下:

function uniqueElements(a) {
  var r = true;
  while (a) {
    var [el, a] = [a.slice(0,1), a.slice(1)];
    r &= !a.includes(el);
  };
  return !!r;
}

此方法有效。但是,由于我采用了更具功能性的风格,并且因为折叠非常棒,我想实现一个看起来像这样的函数:

function uniqueElements(a) {
  var isUnique = (acc, el) => acc &= !remainingArray.includes(el);
  return a.reduce(isUnique, true);
}

我无法弄清楚如何到达remainingArray变量。有人知道怎么做吗?这在JS中是否可行,如果不是,那么该功能如何通过折叠来表达?

2 个答案:

答案 0 :(得分:2)

记住不要陷入思维模式。折叠很棒,但是在JavaScript中,如果我们的结果可以在遍历整个数组之前计算,则无法提前停止折叠

换句话说,以下是什么答案? truefalse

uniqueElements ( [ 1 , 1 , 2 , 3 , ... thousands more items ] )
// => true or false ?

我们可以在处理完第二个false后立即确定答案1。我们无需在23或其他数组中保持折叠,因为它们不会影响false结果

可能的解决方案是一个简单的递归过程



const isUnique = ([ x, ... xs ], set = new Set ()) =>
  x === undefined
    ? true
    : set.has (x)
      ? false // we already found a non-unique, stop recurring
      : isUnique (xs, set.add (x))
      
console.log (isUnique ([]))
// true

console.log (isUnique ([ 1, 2, 3 ]))
// true

console.log (isUnique ([ 1, 1, 2, 3 ]))
// false




或者仍然保持纯粹功能界面的堆栈安全解决方案 - 如果我不得不猜测,这可能比上述程序快10倍并且不会暴露私有API



const isUnique = xs =>
  {
    const set = new Set ()
    for (const x of xs)
      if (set.has (x))
        return false
      else
        set.add (x)
    return true
  }

console.log (isUnique ([]))
// true

console.log (isUnique ([ 1, 2, 3 ]))
// true

console.log (isUnique ([ 1, 1, 2, 3 ]))
// false




或者制定自己的解决方案 - 无论哪种方式,都不要陷入困境,认为只要您触摸可遍历的数据结构,就需要使用折叠。

从更一般的意义上说,你需要练习想象你的函数的过程是什么样的。我建议您在使用铅笔和纸张时使用编译器/评估器,而您首先要掌握它。最终,您将能够设想出简单的过程;然后是随着时间的推移练习更复杂的 - 我说这是因为如果你能看到在之后继续折叠看起来多么愚蠢,你可能无法完成这个任务。结果可以返回

就此而言,这就是为什么我使用Set来检查唯一身份而不是.includes。集合可以进行二进制搜索,而数组搜索是线性的 - 一旦你可以看到对于一个非常大的输入看起来是什么样的过程,一个一个地查找你的项目就像是傻了。只有在您构想过程时,您才能看到像Set这样的替代数据结构如何能够显着降低函数的时间复杂度

答案 1 :(得分:0)

您可以对数组进行切片:

function isUnique(xs) {
  return xs.reduce((acc, x, i) => {
    if (xs.slice(i + 1).includes(x)) {
      return false;
    }
    return acc;
  }, true);
}

尽管如评论中所述,如果数组中有字符串或数字,也可以使用哈希值来获得更好的性能。