7
\$\begingroup\$

I just wanted to share my newly created JavaScript code. This code is responsible for passing back only the unique elements for a given array. This one is quite useful when you have a huge array and you store objects with huge arrays.

Use case: you want to sort out all unique object to do provide a filtering mechanism based on the chips!

Like the array is the following:

[
    {
        "name": "custom object1",
        "chips": [
            {
                "name": "hello"
            },
            {
                "name": "war"
            }
        ]
    },
    {
        "name": "custom object2",
        "chips": [
            {
                "name": "hello"
            },
            {
                "name": "option"
            }
        ]
    }
]

The function:

function getUnique(array, props, level = 0) {
    var retArray = [];
    array.forEach(function (element) {
        var index = props[level];
        if (Array.isArray(props) && props.length - 1 > level) {
            if (element[index] !== undefined) {
                var res = getUnique(element[index], props, level + 1);
                res.forEach(function (subelement) {
                    if (!retArray.some(function (arrayItem) {
                        return arrayItem === subelement;
                    })) {
                        retArray.push(subelement);
                    }
                });
            }
        } else {
            if (element[index] !== undefined && !retArray.some(function (arrayItem) {
                return arrayItem === element[index];
            })) {
                retArray.push(element[index]);
            }
        }
    });
    return retArray;
}

How to call the function:

getUnique(array, ['chips', 'name']);

That's it in a nutshell. What do you think? Any suggestions or advice?

\$\endgroup\$
2
\$\begingroup\$

The function is a bit repetitive, as both cases (iterating over sub array vs individual elements) check if the element is undefined and if the return array includes that value. That could potentially be abstracted to a separate function or simplified.


It appears that the following line:

var index = props[level];

Could be moved outside of the forEach function, since it doesn't depend on any of the variables defined inside the callback function.


If you know that the values to be compared will most likely be primitive values like strings or integers then Array.includes() could likely be used to replace the calls to retArray.some(). While it may not reduce the computational complexity, it would allow simplifying the code to check for existing values. Note that function isn't supported by IE and other older browsers, and is case-sensitive when comparing strings and characters1

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.