I have been racking my brain on how to filter through an array with multiple criteria. I kept looking online, but there was always at least one factor that made the solution not work for my array and use case.
I have a large nested array that I need to filter down by two criteria:
Criteria 1: if there are no duplicates in the client name elements (testArray[i][1]
) then add keep in array
Criteria 2: if there are duplicates in the client name elements (testArray[i][1]
) and those duplicates do not have duplicate product codes (testArray[i][2]
) then keep all records with the same client name elements, but only keep the first records with unique product codes (testArray[i][2]
).
Here is a sample array so I don’t give out client info:
let testArray = [
["ASDF245", "Jeff Hill", "BOP"],
["ASCG285", "Jerry F Tate", "BOP"],
["ASDF240", "Jeff Hill", "WC"],
["ASDF291", "Jake Sab", "BOP"],
["ASDF301", "Mary Stein", "WC"],
["ASDF460", "Jeff Hill", "WC"],
["ASDF245", "Hello Dup", "BOP"],
["ASDF245", "Hello Dup", "BOP"],
["ASDF245", "Hello Dup", "WC"]
];
I have tried using nested for loops, filter functions, foreach functions, etc. I can always get them to get through the first criteria, but not the second. This is one of my latest attempts:
let newArray = [];
for (let b = 0; b < testArray.length; b++) {
newArray.push(["s","s","s"]);
}
let count = 0;
let tempArrayOne = [];
let tempArrayTwo = [];
for (let i = 0; i < testArray.length; i++) {
for (let j = 0; j < testArray.length; j++) {
if (testArray[i][1] == testArray[j][1]) {
count++;
}
}
if (count == 1) {
newArray.push(testArray[i])
}
if (count > 1) {
Logger.log(testArray[i][1]);
tempArrayOne = testArray.filter((iTwo, jTwo) => {
if (iTwo[1] == testArray[i][1]) {
return iTwo[jTwo];
}
})
Logger.log(tempArrayOne)
//Logger.log(tempArrayTwo.findIndex((item) => {return item[1] == tempArrayOne[0][1]}));
//Logger.log(tempArrayTwo);
if (tempArrayTwo.findIndex((item) => {return item[1] == tempArrayOne[0][1]}) == -1.0) {
//for(let s = 0; s < tempArrayOne)
newArray = [...newArray, ...tempArrayOne];
tempArrayTwo = [...tempArrayTwo, ...tempArrayOne];
}
}
count = 0;
Logger.log(newArray);
}
newArray.splice(0, testArray.length);
Logger.log(newArray);
I feel super dumb because I think I am just overthinking the solution. For some reason, the filter function works on the first duplicate ("Jeff Hill"), but it doesn’t work on the second duplicate ("Hello Dup"). For "Hello Dup" it just makes tempArrayOne
an empty array, thus making the whole function pull an error.
2
Answers
Objects in JavaScript are your friend when it comes to removing duplicates. All you need to do is come up with the right key — in your case the name and the product.
You can use
Set
to keep track of unique pairs, in the most cases it’s faster than an object. The more items the more is difference.