首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >降压法中蓄电池/电流滤波的区别是什么

降压法中蓄电池/电流滤波的区别是什么
EN

Stack Overflow用户
提问于 2020-01-24 04:19:39
回答 2查看 157关注 0票数 1

当将Array.prototype.reduceArray.prototype.filter链接时,当过滤当前值而不是累加器值时(概念上和外壳下)有什么区别?

代码语言:javascript
运行
复制
// function union creates a union of all values that appear among arrays
// example A

const union = (...arrays) => {
    return arrays.reduce((acc, curr) => {
      const newElements = acc.filter(el => !curr.includes(el));

      return curr.concat(newElements);
    });
  };
 console.log(union([1, 10, 15, 20], [5, 88, 1, 7], [1, 10, 15, 5]));

// output (7) [1, 10, 15, 5, 88, 7, 20]

// example B

const union = (...arrays) => {
    return arrays.reduce((acc, curr) => {
      const newElements = curr.filter(el => !acc.includes(el));

      return acc.concat(newElements);
    });
  }; 
  console.log(union([1, 10, 15, 20], [5, 88, 1, 7], [1, 10, 15, 5]));

//output (7) [1, 10, 15, 20, 5, 88, 7]

输出的差异表明,数组的计算顺序是“相反的”。据我所知,在使用arr.filter时,值是从头到尾计算的,而对于curr.filter则相反。此外,如果您通过累加器或当前值进行筛选,它们是否还依赖于其他的后果?这会在不同的上下文中抛出错误吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-24 05:38:22

问题不在于filterreduce中的使用,而在于您使用acccurr的顺序。

当我遇到这种看似奇怪的不一致时,我通常采取的第一步是创建一个测试用例并手动运行它。在这里,你已经为我们创建了一个测试用例.

代码语言:javascript
运行
复制
const testData = [
  [1, 10, 15, 20],
  [5, 88, 1, 7],
  [1, 10, 15, 5],
]

现在,我们需要运行每个版本的函数,并查看每个阶段的输出。

有一件事要注意(直到今天晚上我才知道!)如果reduce没有接收到一个initialValue作为第二个参数,它将使用数组中的第一个项作为initialValue。这意味着我们只需要考虑每个函数的2次执行,而不是3次。

例A

代码语言:javascript
运行
复制
const union = (...arrays) => {
  return arrays.reduce((acc, curr) => {
    const newElements = acc.filter(el => !curr.includes(el))

    return curr.concat(newElements)
  })
}

在该函数的第一个版本中,对正在发生的事情的简短描述是,我们正在循环累加器(acc),并删除当前正在比较的数组(curr)中已经存在的所有项。然后我们将这个列表添加到curr的末尾。

事实上,我们正在将newElements推向curr的末尾,这一点很重要。这就是为什么两个不同版本的订单是不同的。

第一次执行

代码语言:javascript
运行
复制
const acc = [1, 10, 15, 20]
const curr = [5, 88, 1, 7]
const newElements = [10, 15, 20] // these elements exist in acc but not in curr
curr.concat(newElements) === [5, 88, 1, 7, 10, 15, 20]

第二次执行

代码语言:javascript
运行
复制
const acc = [5, 88, 1, 7, 10, 15, 20] // carried over from first execution
const curr = [1, 10, 15, 5]
const newElements = [88, 7, 20] // these elements exist in acc but not in curr
curr.concat(newElements) === [1, 10, 15, 5, 88, 7, 20]

例B

代码语言:javascript
运行
复制
const union = (...arrays) => {
  return arrays.reduce((acc, curr) => {
    const newElements = curr.filter(el => !acc.includes(el))

    return acc.concat(newElements)
  })
}

在该函数的第一个版本中,对正在发生的事情的简短描述是,我们正在遍历当前正在比较的数组(curr),并删除累加器(acc)中已经存在的所有项。然后我们将这个列表添加到acc的末尾。

在下面的第一次执行结束时,您已经可以看到结果是以一种非常不同的顺序产生的。

第一次执行

代码语言:javascript
运行
复制
const acc = [1, 10, 15, 20]
const curr = [5, 88, 1, 7]
const newElements = [5, 88, 7] // these elements exist in curr but not in acc
acc.concat(newElements) === [1, 10, 15, 20, 5, 88, 7]

第二次执行

代码语言:javascript
运行
复制
const acc = [1, 10, 15, 20, 5, 88, 7] // carried over from first execution
const curr = [1, 10, 15, 5]
const newElements = [] // these elements exist in acc but not in curr
acc.concat(newElements) === [1, 10, 15, 20, 5, 88, 7]

结论

简单地回答你的问题是,累加器上的过滤和当前数组之间的区别是,只要输入不同,结果就会不同。‍♂️

此外,如果您通过累加器或当前值进行筛选,它们是否还依赖于其他的后果?这会在不同的上下文中抛出错误吗?

幸运的是,没有任何关于错误的担忧。但是值得注意的是,您的函数的第二个版本是~10%,而不是第一个版本。我猜这完全是间接的。不同的测试数据集可能产生不同的性能结果。

票数 1
EN

Stack Overflow用户

发布于 2020-01-24 07:52:33

例如,在1中,当您连接这两个列表时,您要确保acc模拟器不会包含来自current的任何元素。

另一方面,在2中,您要确保current不会包含已经存在于acc模拟器中的任何元素。

差异在于元素显示的最终顺序。

我认为这两个示例都没有效率,因为它们都涉及到O(n2)时间复杂性,因为您正在嵌套迭代。第二个,正如其他人所说的,可能会有一些更好的性能,因为嵌套的迭代将在可能比累加器短的块上进行。

我宁愿写得差不多像这样:

代码语言:javascript
运行
复制
const union = (...tuples) => Array.from(
  new Set(
    tuples.flatMap(n => n),
  )
);



console.log(
  union([1, 10, 15, 20], [5, 88, 1, 7], [1, 10, 15, 5]),
);

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59890313

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档