简体   繁体   English

如何从数组中删除哪些元素是另一个数组的元素?

[英]How can remove elements from array which elements are another array?

I have two arrays which values are: 我有两个值分别为的数组:

const allValues = ["111", "111", "111", "222", "111", "222"]

const removingValues = ["111", "111", "222"]

And I want this array. 我想要这个数组。

const remaningValues = ["111", "222", "111"]

I have to tried _.difference(allValues, removingValues) but it given empty array. 我不得不尝试_.difference(allValues, removingValues)但是它给出了空数组。 How can I do that in simple way? 我如何以简单的方式做到这一点?

the first array includes "111" : 4 times and "222" : 2 times the removing values from this array are "111" : 2 times "222" : 1 times and the remaining values should be : "111" : 4-2 = 2 and "222" : 2-1 = 1 第一个数组包含"111" : 4 times"222" : 2 times ,从该数组中删除的值是"111" : 2 times "222" : 1 times ,其余值应为: "111" : 4-2 = 2"222" : 2-1 = 1

You could use this function: 您可以使用以下功能:

 const allValues = ["111", "111", "111", "222", "111", "222"]; const removingValues = ["111", "111", "222"]; const result = allValues.filter(s => { let i = removingValues.indexOf(s); return i > -1 && removingValues.splice(i, 1); }); console.log(result); 

The above has a time complexity of O(n²) , so if you are working with large arrays it will be better to create a hash of some sort, for example using a Map , which will give a O(n) time complexity: 上面的时间复杂度为O(n²) ,因此,如果您使用大型数组,则最好创建某种哈希,例如使用Map ,这将带来O(n)时间复杂度:

 const allValues = ["111", "111", "111", "222", "111", "222"]; const removingValues = ["111", "111", "222"]; const map = new Map(removingValues.map(s => [s, 0])); removingValues.forEach(s => map.set(s, map.get(s)+1)); const result = allValues.filter(s => { let i = map.get(s); return i && map.set(s, i-1); }); console.log(result); 

The order of your expected remaining values makes little sense to me. 您期望的剩余值的顺序对我来说毫无意义。 If you are ok with ['111', '111', '222'] (instead of ['111', '222', '111'] ), then this simple code should do it: 如果您对['111', '111', '222']感到满意(而不是['111', '222', '111'] ),那么此简单的代码应该可以做到:

 const without = (i, xs) => i > -1 ? xs.slice(0, i).concat(xs.slice(i + 1)) : xs const removeAll = (all, rems, idx = all .indexOf (rems[0])) => rems .length ? removeAll (without (idx, all), rems .slice(1)) : all const allValues = ["111", "111", "111", "222", "111", "222"]; const removingValues = ["111", "333", "111", "222"]; console .log ( removeAll (allValues, removingValues) ) 

The helper function without just return a copy of the old array with the given index not included. 助手功能without只是返回旧阵列的副本不包含给定的指标。

removeAll is a simple recursion on the things to remove. removeAll是对要删除的事物的简单递归。 If it's empty, we return the remaining list. 如果为空,则返回其余列表。 Otherwise, we remove from our list the first index that matches the first element to remove, and pass that and the remaining items to match back into removeAll . 否则,我们将从列表中删除与要删除的第一个元素匹配的第一个索引,并将该索引和其余要匹配的项传递回removeAll

You can do this in a very concise way with Array.reduce , Array.splice and Array.indexOf like this: 您可以使用Array.reduceArray.spliceArray.indexOf以非常简洁的方式执行此操作,如下所示:

 const vals = ["111", "111", "111", "222", "111", "222"] const rms = ["111", "111", "222"] let r = rms.reduce((r,c) => (r.splice(r.indexOf(c), 1) && r), [...vals]) console.log(r) 

The idea is to start from the values to remove and in the Array.reduce put as a starting value for the accumulator an actual copy of the allValues . 这个想法是从要删除的值开始,然后在Array.reduce中将allValues的实际副本作为累加器的初始值放置。 Then inside of the reduce just remove the values which match the indexOf via Array.splice 然后在reduce内部,通过Array.splice删除与indexOf匹配的值

The copy of the vals is so that we do not mutate the original array. vals的副本是这样的,因此我们不会mutate原始数组。 If you do not care about mutating that you can just have: 如果您不关心变异,则可以执行以下操作:

let r = rms.reduce((r,c) => (r.splice(r.indexOf(c), 1) && r), vals)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM