[英]How can remove elements from array which elements are another array?
我有兩個值分別為的數組:
const allValues = ["111", "111", "111", "222", "111", "222"]
const removingValues = ["111", "111", "222"]
我想要這個數組。
const remaningValues = ["111", "222", "111"]
我不得不嘗試_.difference(allValues, removingValues)
但是它給出了空數組。 我如何以簡單的方式做到這一點?
第一個數組包含"111" : 4 times
和"222" : 2 times
,從該數組中刪除的值是"111" : 2 times
"222" : 1 times
,其余值應為: "111" : 4-2 = 2
和"222" : 2-1 = 1
您可以使用以下功能:
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);
上面的時間復雜度為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);
您期望的剩余值的順序對我來說毫無意義。 如果您對['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) )
助手功能without
只是返回舊陣列的副本不包含給定的指標。
removeAll
是對要刪除的事物的簡單遞歸。 如果為空,則返回其余列表。 否則,我們將從列表中刪除與要刪除的第一個元素匹配的第一個索引,並將該索引和其余要匹配的項傳遞回removeAll
。
您可以使用Array.reduce , Array.splice和Array.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)
這個想法是從要刪除的值開始,然后在Array.reduce中將allValues
的實際副本作為累加器的初始值放置。 然后在reduce內部,通過Array.splice
刪除與indexOf
匹配的值
vals
的副本是這樣的,因此我們不會mutate
原始數組。 如果您不關心變異,則可以執行以下操作:
let r = rms.reduce((r,c) => (r.splice(r.indexOf(c), 1) && r), vals)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.