I have a fairly simple nested array of objects. Each object is composed of 5 (string) values, e.g. [“0,0”, “0,0”, “0,0”, “0,0”, “0,1”]. There are no variables attached, hence using arrays inside an array.
Each object represents a puzzle solve permutation being tested by other parts my code. The main data set is composed of 150k permutations.
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"]]
I want to filter this ‘haystack’, but each object in the array must pass 3 filters (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");
If it fails any single filter, it should not carry over to the new array.
So this line:
["0,0", "0,0", "0,0", "0,0", "2,2"],
would pass the needle3 filter, but not the needle1 filter.
The new array would include only those objects in the old array that pass all three tests.
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"]];
I have found code that would filter for any of a number of elements present, regardless of position:
let needle1 = ["4,2", "0,0", "2,1"]; const haystack2 = haystack.filter(item => needle1.every(val => item.indexOf(val) > -1));
would return:
[ [ “0,1”, “0,0”, “4,2”, “1,0”, “2,1” ] ]
but it isn’t exactly what I’m looking for. I want ‘this’ or ‘this’ or ‘this’, rather than ‘this’ & ‘this’ & ‘this’.
In other parts of my code, I worked through the array with something like this:
let needle1 = haystacks[i].includes("0,1" || "3,0" || "3,2" || "4,2");
and then in the main loop, I simply skipped past the object with something like.
if (needle1 !== true) {skipObject(); return;} if (needle2 !== true) {skipObject(); return;} if (needle3 !== true) {skipObject(); return;}
But the javascript file is currently over the 10MB limit with such a big dataset of permutations, and my goal is to thin the array of permutations I know don’t work.
Any hints as to a solution would be useful.
Tested this suggestion from @Ethan_Snow, but it’s outputting 15 objects to the array instead of 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);
Advertisement
Answer
If im understanding your question correctly, you Can use filter and Array.some, and check that it satisfies every needle
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);
This should check that atleast One item from each “needle” in needles is in the stack, and filters out stacks that dont meet all three