reectrix
reectrix

Reputation: 8629

Lodash to find if object property exists in array

I have an array of objects like this:

[ {"name": "apple", "id": "apple_0"}, 
  {"name": "dog",   "id": "dog_1"}, 
  {"name": "cat", "id": "cat_2"}
]

I want to insert another element, also named apple, however, because I don't want duplicates in there, how can I use lodash to see if there already is an object in the array with that same name?

Upvotes: 29

Views: 127842

Answers (7)

Nenad Vracar
Nenad Vracar

Reputation: 122145

You can use Lodash _.find() like this.

var data = [ {"name": "apple", "id": "apple_0"}, 
  {"name": "dog",   "id": "dog_1"}, 
  {"name": "cat", "id": "cat_2"}
]

if(!_.find(data, {name: 'apple'})) {
  data.push({name: 'apple2'});
}
console.log(data)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

Reference documentation: https://lodash.com/docs/4.17.14#find

Upvotes: 51

Alex Quintero
Alex Quintero

Reputation: 1179

This is Form

_.has(object, path)

Example:

const countries = { country: { name: 'Venezuela' } }
const isExist = _.has(countries, 'country.name')
// isExist = true

For more information Document Lodash

Upvotes: 14

Mihai
Mihai

Reputation: 2967

Here are three ways of achieving this using lodash 4.17.5:

Say you want to add object entry to an array of objects numbers, only if entry does not exist already.

let numbers = [
    { to: 1, from: 2 },
    { to: 3, from: 4 },
    { to: 5, from: 6 },
    { to: 7, from: 8 },
    { to: 1, from: 2 } // intentionally added duplicate
];

let entry = { to: 1, from: 2 };

/* 
 * 1. This will return the *index of the first* element that matches:
 */
_.findIndex(numbers, (o) => { return _.isMatch(o, entry) });
// output: 0


/* 
 * 2. This will return the entry that matches. Even if the entry exists
 *    multiple time, it is only returned once.
 */
_.find(numbers, (o) => { return _.isMatch(o, entry) });
// output: {to: 1, from: 2}


/* 
 * 3. This will return an array of objects containing all the matches.
 *    If an entry exists multiple times, if is returned multiple times.
 */
_.filter(numbers, _.matches(entry));
// output: [{to: 1, from: 2}, {to: 1, from: 2}]


/* 
 * 4. This will return `true` if the entry exists, false otherwise.
 */
_.some(numbers, entry);
// output: true

If you want to return a Boolean (i.e., assuming that you are not using _.some()), in the first case, you can simply check the index value that is being returned:

_.findIndex(numbers, (o) => { return _.isMatch(o, entry) }) > -1;
// output: true

Lodash documentation is great source of examples and experimentation.

Upvotes: 1

reectrix
reectrix

Reputation: 8629

This is what worked for me (after testing out the different solutions):

  addItem(items, item) {
    let foundObject = _.find(items, function(e) {
      return e.value === item.value;
    });

    if(!foundObject) {
      items.push(item);
    }
    return items;
  }

Upvotes: 5

acontell
acontell

Reputation: 6932

If you're interested in inserting in the array only one value, then using _.find could be an option. However, if you were interested in inserting one or more than one, I'd suggest using _.unionBy instead:

var currentArr = [{
    "name": "apple",
    "id": "apple_0"
  }, {
    "name": "dog",
    "id": "dog_1"
  }, {
    "name": "cat",
    "id": "cat_2"
  }],
  arrayOneValue = [{
    "name": "apple",
    "id": "apple_0"
  }],
  arrayTwoValues = arrayOneValue.concat({
    "name": "lemon",
    "id": "lemon_0"
  })

console.log(_.unionBy(currentArr, arrayOneValue, 'name'));
console.log(_.unionBy(currentArr, arrayTwoValues, 'name'));
// It also allow you to perform the union using more than one property
console.log(_.unionBy(currentArr, arrayTwoValues, 'name', 'id'));
<script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>

Upvotes: 1

Jorge Mejia
Jorge Mejia

Reputation: 1163

Here is an other example with lodash

var a = [ {"name": "apple", "id": "apple_0"}, 
  {"name": "dog",   "id": "dog_1"}, 
  {"name": "cat", "id": "cat_2"}
]

var b = _.find(a, ['name', "apple2"]);

if(_.isObject(b)){
  console.log('exists')
}else{
    console.log('insert new')
}

https://jsfiddle.net/jorge182/s4og07jg/

Upvotes: 5

Ori Drori
Ori Drori

Reputation: 193258

You can use Array.prototype.find() or lodash's _.find():

const addItem = (arr, item) => {
  if(!arr.find((x) => x.name === item.name)) { // you can also change `name` to `id`
    arr.push(item);
  }
};

const arr = [ 
  {"name": "apple", "id": "apple_0"}, 
  {"name": "dog",   "id": "dog_1"}, 
  {"name": "cat", "id": "cat_2"}
];

addItem(arr, { "name": "apple", "id": "apple_0" });

addItem(arr, { "name": "pear", "id": "pear_3" });

console.log(arr);

And a bit shorter but less readable version:

    const addItem = (arr, item) => arr.find((x) => x.name === item.name) || arr.push(item); // you can also change `name` to `id`

    const arr = [ 
      {"name": "apple", "id": "apple_0"}, 
      {"name": "dog",   "id": "dog_1"}, 
      {"name": "cat", "id": "cat_2"}
    ];

    addItem(arr, { "name": "apple", "id": "apple_0" });

    addItem(arr, { "name": "pear", "id": "pear_3" });

    console.log(arr);

Upvotes: 5

Related Questions