删除基于另一个数组的嵌套数组

时间:2019-12-29 21:55:14

标签: javascript arrays

我有这个嵌套数组

let arr = [['first', 'second'], ['third', 'fourth'], ['second', 'third']]

现在我要基于此数组进行过滤/删除。

let filter = ['first', 'second']

现在我的预期输出应该是:

[['third', 'fourth'], ['second', 'third']]

我只有这段代码:

arr.filter(str => str.indexOf('second') === -1)

没有给出预期的输出,它也删除了['second', 'third'],因为它过滤了包含'second' ..的任何元素,因此它们必须是一种更好的方法或改进代码。

3 个答案:

答案 0 :(得分:1)

您可以使用filter来检查元素是否不包含过滤器数组的每个字符串。

let arr = [['first', 'second'], ['third', 'fourth'], ['second', 'third']]

let filterout = ['first', 'second']

let arr2 = arr.filter(x => ! filterout.every(y => x.includes(y)))

console.log(arr2)

但是通过使用filter它基本上创建了一个具有更少元素的新数组。对于一个小的阵列,这已经足够了。

如果目标是直接更改原始数组,则可以从该数组中拼接这些元素。

let arr = [ ['first', 'second'], ['third', 'fourth'], ['second', 'third'], ['second', 'first'] ]

let filterout = ['first', 'second']

// getting the indexes of the element that need to be removed
let idxArr = []
arr.forEach( (x, idx) => { if(x.every(y => filterout.includes(y))) idxArr.push(idx)})

// removing the elements from the array
idxArr.sort((i,j)=>j-i).forEach(idx => {arr.splice(idx, 1)})

console.log(arr)

答案 1 :(得分:1)

您需要测试两个数组是否相等。 [执行此操作的方法有很多],但是一旦选择了一个,就可以简单地删除与另一个数组相等的任何数组。为了避免重新实现,我将使用LoDash _.isEqual进行演示:

let arr = [['first', 'second'], ['third', 'fourth']]

let filter = ['first', 'second']

let result = arr.filter(item => !_.isEqual(filter, item));

console.log(result);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>

相等函数可以交换到您满意的任何实现中。一个非常简单的方法就是:

function isEqual(a, b) {
  return JSON.stringify(a) === JSON.stringify(b);
}

,但不能保证它是正确的(例如isEqual([1, 2], ["1,2"]) //true),输入较大时,它会变慢。但它可能仍然有效,具体取决于情况。

答案 2 :(得分:1)

如果您关心排序并需要完全匹配,则可以编写一个简单的数组equal方法,然后过滤掉所有相等的数组:

const arrEq = (a, b) => a.length === b.length && a.every((e, i) => b[i] === e);

const arr = [['first', 'second'], ['third', 'fourth'], ['second', 'third']];
const filter = ['first', 'second'];

console.log(arr.filter(e => !arrEq(e, filter)));

如果您希望使用相同的元素,但顺序无关紧要:

const arrItemsEq = (a, b, cmp) => {
  if (a.length !== b.length) {
    return false;
  }
  
  a = a.slice().sort(cmp);
  b = b.slice().sort(cmp);
  return a.every((e, i) => e === b[i]);
};

const arr = [["a", "b"], ["b", "c"]];
const filter = ["b", "a"];

const strCmp = (x, y) => x.localeCompare(y);
console.log(arr.filter(e => !arrItemsEq(e, filter, strCmp)));

如果您想过滤掉arr个元素中的至少一个filter个元素,则将它们过滤掉:

const arr = [["a", "b"], ["b", "c"]];
const filter = ["b", "a"];

console.log(arr.filter(x => !filter.every(y => x.includes(y))));