Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to search an array for duplicate by using substring

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'
like image 574
Alex Avatar asked May 02 '26 01:05

Alex


1 Answers

Using Object.groupBy

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])

Custom Implementation

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])
like image 192
GLJ Avatar answered May 03 '26 13:05

GLJ



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!