How to check if items exists in array before save it?

Hi,
I am sutcked with a piece of code that I can’t make it works:
I have this array of objects:

selectedItem[
{title: "Innovation", id: "3443klk4-4lkl34kl"},
{title: "Sales", id: "fffffs3-4lkl34kl"}
]

Each object represent a tag. In the interface the user can click on a tag which is saved in this array of object.
What I am trying to do is avoid saving the tag in the array if the user click it twice by checking the id.
If the id already exists in the array then the correspondig clicked tag should not be saved other wise it get saved in the array.

How can I check if the id are the same? I tested selectedItem.find but the editor says that the find method doesn’t exists in selectedItem.

Best regards
Americo

All JS Array objects should have a .find() method, I would ensure selectedItem is an Array.

let selectedItem = [
    {title: "Innovation", id: "3443klk4-4lkl34kl"},
    {title: "Sales", id: "fffffs3-4lkl34kl"}
]
const findByPropInObjectArray = (arr, prop) => match => arr.find(e => e[prop] === match);
const findID = findByPropInObjectArray(selectedItem, "id");

findID("3443klk4-4lkl34kl");
findID("3443klk4-4lkl34kl") ? true : false;
// {title: "Innovation", id: "3443klk4-4lkl34kl"}
//true

findID("DoesNotExist");
findID("DoesNotExist") ? true : false;
// undefined
//false

Thanks!
Its working as I spected.
I have just two questions:
How should I read the line where you create the findByPropInObjectArray constant? When I say read I mean in human language.

Now my code looks like this (I leave out the object part since is already in the post):

if(selectedTags.length === 0) {
            selectedTags.push(allDialogItems[index]);
        } else {
            const findIdInSelectedTags = (arr, prop) => match => arr.find(e => e[prop] === match);
            const findID = findIdInSelectedTags(selectedTags, 'id');
            
            if(!findID(allDialogItems[index].id)) {
                selectedTags.push(allDialogItems[index]);
            } else {
                return;
            }
        }

I would like to take this code, or the part inside the “else” and apply the same logic using “map”. Is that possible?

And thanks again!
/Americo

function findByPropInObjectArray(arr, prop) {
    /* Uses currying to return a function that finds a specific object property value,
       and returns said object */
    // Step 1, initialize 'findPropInObjectArray() with an array
    // & an object property to pass along to function searchForMatch
    return function searchForMatch(match) {
        // This function is what becomes findID(), if "id" was passed
        // as prop
        return arr.find(function (obj) {
            // the <array>.find() method requires a callback function
            // This translates to "search object for object[property] === match"
            // return object which matches that expression
            // Ex: selectedTags[0]["id"] === "3443klk4-4lkl34kl"
            return obj[prop] === match
        });
    };

};

This was a general example that allows you to search any array of objects for any property & property value.
If you only ever need to search this array, and the id property, and we assume this function has access to the selectedTags variable you could simplify this to:

function findID(match) {
    return selectedTags.find(function (obj) {return obj.id === match})
}

I actually think you have a pretty decent method for adding the item to selectedTags. The issue with map in this case is that it will always return an array with the same length as the original array, while you need to increase the array’s length (potentially). If you want to practice your functional programming methods though, you could use filter instead of find to extract a match:

    // If no matches, matches.length is 0, if (!0) evaluates to true
    const matches = selectedTags.filter(obj => obj.id === allDialogItems[index].id)
    if (!matches.length) selectedTags.push(allDialogItems[index])
1 Like

Thank you very much for your time and explanation.
I will save this post in my favorites.

thanks a lot!

Regads
Americo