I am trying to filter an array for duplicate values by splitting/substring the elements.
I need to split these data by "-" and search for duplicate string after the "-" and write the element with the duplicate string to the duplicate array.
Here is what I am working on:
var arr = ['abc-10.10.10.0/22','abc-10.01.21.0/22','abc-10.01.01.0/22','abcd-10.01.01.0/22'];
var duplicates = [];
arr.forEach(function (value, index, array) {
if (array.indexOf(value, index + 1) !== -1
&& duplicates.indexOf(value) === -1) {
duplicates.push(value);
}
});
console.log("Duplicate values:", duplicates);
//Desired output 'abc-10.01.01.0/22','abcd-10.01.01.0/22'
Simplest implementation - just group by the substring, and return all results with a count > 1.
function getDuplicates(xs, selector) {
const group = Object.groupBy(xs, selector);
return Object.keys(group)
.filter(k => group[k].length > 1)
.map(k => group[k])
.flat();
}
var arr = ['abc-10.10.10.0/22','abc-10.01.21.0/22','abc-10.01.01.0/22','abcd-10.01.01.0/22'];
getDuplicates(arr, (x) => x.split('-')[1])
In this case, you are trying to solve for a unique on the selector, but keep the original values. With this, we need to keep track both of the duplicate substrings, and what substrings link to the original value.
This implementation is tightly solved for this problem, and the only benefit is not needing to filter before selecting the values at the cost of an additional set. I don't think this is worth the possible slight performance gain (code is harder to maintain / less easy to understand, increased space complexity), but I've provided it nonetheless.
function getDuplicates(xs, selector) {
const selectSet = new Set(); // list of all duplicate found selectors
const selectToXs = {}; // key of selector to return original values
for(const x of xs) {
const sub = selector(x);
if (sub in selectToXs) {
selectSet.add(sub);
selectToXs[sub].add(x);
} else {
selectToXs[sub] = new Set([x]);
}
}
return [...selectSet].map((s) => [...selectToXs[s]]).flat();
}
var arr = ['abc-10.10.10.0/22','abc-10.01.21.0/22','abc-10.01.01.0/22','abcd-10.01.01.0/22'];
getDuplicates(arr, (x) => x.split('-')[1])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With