首页 > 解决方案 > Javascript过滤嵌套数组以排除不包含多个元素之一的对象

问题描述

我有一个相当简单的嵌套对象数组。每个对象由 5 个(字符串)值组成,例如 ["0,0", "0,0", "0,0", "0,0", "0,1"]。没有附加变量,因此在数组中使用数组。

每个对象代表一个拼图解决排列,我的代码正在测试其他部分。主数据集由 150k 个排列组成。

let haystack = [
["1,0", "0,0", "0,0", "0,0", "0,0"],
["0,0", "0,2", "0,0", "0,0", "0,1"],
["2,2", "0,0", "4,2", "0,2", "1,1"],
["0,0", "0,0", "3,0", "0,0", "2,1"],
["0,0", "0,0", "0,0", "0,0", "2,2"],
["0,0", "0,2", "0,0", "0,0", "3,2"],
["0,0", "0,0", "0,1", "0,0", "0,3"],
["0,0", "0,1", "0,0", "1,0", "3,0"],
["0,1", "0,0", "4,2", "1,0", "2,1"],
["0,3", "0,0", "0,1", "0,0", "3,2"],
["0,0", "3,2", "0,0", "1,0", "0,2"],
["0,0", "1,0", "0,0", "1,0", "4,2"],
["0,0", "0,0", "0,0", "1,0", "2,2"],
["0,0", "0,0", "0,0", "1,0", "3,2"],
["0,2", "3,2", "0,1", "1,0", "0,1"]]

我想过滤这个“干草堆”,但数组中的每个对象都必须通过 3 个过滤器(needle1、needle2、needle3):

let needle1 = haystacks[i].includes("0,1" || "3,0" || "3,2" || "4,2");
let needle2 = haystacks[i].includes("1,0" || "2,0" || "1,2" || "2,2");
let needle3 = haystacks[i].includes("0,0" || "3,2");

如果它未能通过任何单个过滤器,则不应延续到新阵列。

所以这一行:

["0,0", "0,0", "0,0", "0,0", "2,2"],

将通过 needle3 过滤器,但不会通过 needle1 过滤器。

新数组将仅包含旧数组中通过所有三个测试的对象。

newHaystack = [
["2,2", "0,0", "4,2", "0,2", "1,1"],
["0,0", "0,1", "0,0", "1,0", "3,0"],
["0,1", "0,0", "4,2", "1,0", "2,1"],
["0,0", "3,2", "0,0", "1,0", "0,2"],
["0,0", "1,0", "0,0", "1,0", "4,2"],
["0,0", "0,0", "0,0", "1,0", "3,2"],
["0,2", "3,2", "0,1", "1,0", "0,1"]];

我找到了可以过滤任何存在的元素的代码,无论位置如何:

let needle1 = ["4,2", "0,0", "2,1"];

const haystack2 = haystack.filter(item =>
    needle1.every(val => item.indexOf(val) > -1));

会返回:

[ [“0,1”、“0,0”、“4,2”、“1,0”、“2,1”]]

但这并不是我想要的。我想要'this'或'this'或'this',而不是'this' & 'this' & 'this'。

在我的代码的其他部分,我使用这样的方式处理数组:

let needle1 = haystacks[i].includes("0,1" || "3,0" || "3,2" || "4,2");

然后在主循环中,我只是用类似的东西跳过了对象。

if (needle1 !== true) {skipObject(); return;}
if (needle2 !== true) {skipObject(); return;}
if (needle3 !== true) {skipObject(); return;}

但是 javascript 文件目前超过了 10MB 的限制,具有如此大的排列数据集,我的目标是精简我知道不起作用的排列数组。

关于解决方案的任何提示都会很有用。

从@Ethan_Snow 测试了这个建议,但它向数组输出了 15 个对象而不是 7 个。

let needle1 = ["0,1", "3,0", "3,2", "4,2"];
let needle2 = ["1,0", "2,0", "1,2", "2,2"];
let needle3 = ["0,0", "3,2"];
let needles = [needle1, needle2, needle3];
const haystack2 = haystack.filter(stack => {
    return needles.every(needles => {return needles.some(item => stack.includes(item) > -1)
    })
})
console.log(haystack2);

标签: javascriptarraysmultidimensional-arrayfilter

解决方案


如果我正确理解您的问题,您可以使用过滤器和 Array.some,并检查它是否满足每一根针

let needle1 = ["0,1", "3,0", "3,2",  "4,2"];
let needle2 = ["1,0", "2,0", "1,2", "2,2"];
let needle3 = ["0,0", "3,2"];
let needles = [needle1, needle2, needle3]
const haystack2 = haystack.filter(stack => {
    return needles.every(needle => {
        return needle.some(item => stack.includes(item)
    }); 
})

console.log(haystack2);

这应该检查针中每个“针”中的至少一个项目是否在堆栈中,并过滤掉不符合所有三个的堆栈


推荐阅读