如何在Javascript中一次性过滤数组元素 [英] How to get filtered in and out elements of array at one go in Javascript
问题描述
我想知道是否存在一种精确的方法来过滤Javascript中未过滤的数组元素,我的意思是,就像一口气.
I wonder if there is a precise way for getting filtered an unfiltered elements of an array in Javascript, I mean, like, in one go.
当前,我使用如下逻辑:
Currently, I use a logic like follows:
const myArray = ['a', 'b', 'c', 'd', 'e']
const filterArray = ['a', 'b']
// I want to combine those two expressions somehow
const filteredInResult = myArray.filter(e => filterArray.includes(e))
const filteredOutResult = myArray.filter(e => !filterArray.includes(e))
console.log(filteredInResult)
console.log(filteredOutResult)
我感觉像解构可能已经有实现的方法了,但是无论如何,我还是想问你们是否有一种方法可以过滤&出一枪.
I felt like a destructuring-like way might already be there to achieve it, but anyway, I prefer asking you guys if there is a way for getting filtered in & out results in one shot.
编辑:如果此问题与此处类似,请继续提醒我但是我在上面的字符串查询中使用了字符串比较和includes
,但是过滤表达式可能比这更复杂.因此,我必须强调,问题的重点不在两个字符串数组的区别上.我要再举一个例子,希望问题不会合并:D
SO keeps alerting me if this question is similar to the question here, but I used string comparison and includes
for brewity above but the filtering expression may be more complex than that. So, the I must underline that the focus of the question is not on difference of two string arrays. I am leaving another example and hope the questions won't be merged :D
// A more complex use case
const myArray = [
{id: 1, value: 'a'},
{id: 2, value: 'b'},
{id: 3, value: 'c'},
{id: 4, value: 'd'},
{id: 5, value: 'e'},
]
const filterArray = ['a', 'b']
// I want to combine those two expressions somehow
const filteredInResult = myArray.filter(e => filterArray.includes(e.value))
const filteredOutResult = myArray.filter(e => !filterArray.includes(e.value))
console.log(filteredInResult)
console.log(filteredOutResult)
推荐答案
如果您担心在myArray
上进行两次迭代,则可以 first 考虑降低计算复杂度.因为循环的每次迭代都调用Array.prototype.includes
,并且Array.prototype.includes
的复杂度为O(n)
,所以您的代码的总体复杂度为O(n ^ 2)
. (外循环:O(n)
*内循环:O(n)
).因此,请考虑先解决此问题:使用Set和Set.has
(一个O(1)
操作),而不要使用数组和.includes
.假设您的实际filterArray
足够大,以至于需要考虑计算复杂性-设置 do 会产生一些开销.
If you're worried about iterating twice over the myArray
, you might first consider reducing the computational complexity. Because each iteration of the loops calls Array.prototype.includes
, and the complexity of Array.prototype.includes
is O(n)
, your code has an overall complexity of O(n ^ 2)
. (outer loop: O(n)
* inner loop: O(n)
). So, consider fixing that first: use a Set and Set.has
, an O(1)
operation, instead of an array and .includes
. This is assuming that your actual filterArray
is large enough that computational complexity is something to worry about - sets do have a bit of an overhead cost.
对于问题的其他(主要)部分,一个选择是在外部创建两个结果数组,然后在迭代时推入相应的结果数组:
As for the other (main) part of the question, one option is to create the two result arrays outside, then push to the appropriate one while iterating:
const myArray = ['a', 'b', 'c', 'd', 'e']
const filterArray = new Set(['a', 'b'])
const filteredInResult = [];
const filteredOutResult = [];
for (const e of myArray) {
(filterArray.has(e) ? filteredInResult : filteredOutResult).push(e);
}
console.log(filteredInResult)
console.log(filteredOutResult)
也可以使用reduce
,尽管我认为它看起来不太好:
Could also use reduce
, though I don't think it looks very good:
const myArray = ['a', 'b', 'c', 'd', 'e']
const filterArray = new Set(['a', 'b'])
const { filteredInResult, filteredOutResult } = myArray.reduce((a, e) => {
a[filterArray.has(e) ? 'filteredInResult' : 'filteredOutResult'].push(e);
return a;
}, { filteredInResult: [], filteredOutResult: [] });
console.log(filteredInResult)
console.log(filteredOutResult)
这篇关于如何在Javascript中一次性过滤数组元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!