如何在Javascript中一次性过滤掉数组元素

vah*_*det 3 javascript arrays filter

我想知道是否有一种精确的方法来过滤Javascript中未过滤的数组元素,我的意思是,一口气。

当前,我使用如下逻辑:

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)
Run Code Online (Sandbox Code Playgroud)

我觉得可能已经有一种类似解构的方法来实现它,但是无论如何,我更喜欢问你们是否有一种方法可以一次过滤进出结果。

编辑:如果此问题与此处的问题类似,那么SO会不断提醒我,但是我includes在上面使用字符串比较和酿造性,但过滤表达式可能比这更复杂。因此,我必须强调指出,问题重点不在两个字符串数组的区别上。我要再举一个例子,希望问题不会被合并: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)
Run Code Online (Sandbox Code Playgroud)

Cer*_*nce 5

如果您担心在 上迭代两次myArray,您可能首先考虑降低计算复杂度。因为循环的每次迭代都会调用Array.prototype.includes,并且复杂度Array.prototype.includesO(n),所以您的代码的整体复杂度为O(n ^ 2)。(外循环:O(n)* 内循环:)O(n)。因此,可以考虑固定首先:使用Set和Set.has,一个O(1)操作,而不是一个阵列和.includes。这是假设您的实际filterArray值足够大,以至于需要担心计算复杂性 - 集合确实有一些开销成本。

至于问题的另一个(主要)部分,一种选择是在外部创建两个结果数组,然后在迭代时推送到适当的数组:

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)
Run Code Online (Sandbox Code Playgroud)

也可以使用reduce,虽然我认为它看起来不太好:

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)
Run Code Online (Sandbox Code Playgroud)


Nic*_*ons 5

您可以使用.reduce()代替.filter(),在其中使用(数字)布尔值includes()作为累加器的索引,如下所示:

const myArray = ['a', 'b', 'c', 'd', 'e'];
const filterArray = ['a', 'b'];

const [fOut, fIn] = myArray.reduce((a, n) => {
  a[+filterArray.includes(n)].push(n); 
  return a;
}, [[], []]);

console.log(fIn);
console.log(fOut);
Run Code Online (Sandbox Code Playgroud)