Kevin Whitaker
Kevin Whitaker

Reputation: 13435

Javascript: Finding index of an object in an array, based on a value within a nested array on the objects

I have an array that looks like this:

[{
    name: 'foobar',
    fields: [{
        label: 'argle'
    },{
        label: 'bargle'
    }]
},{
    name: 'baz',
    fields: [{
        label: 'rar'
    },{
        label: 'hoogah'
    }]
}]

I'm looking for the index of the object which has a field matching label === 'rar', so I can update that particular field. Is there an optimum way to accomplish this? I know indexOf won't get me there by itself, but I'm struggling with the logic.

Upvotes: 2

Views: 86

Answers (4)

Redu
Redu

Reputation: 26201

an ugly way of doing it.

var data = [
  {name: 'foobar', fields: [{label: 'argle'}, {label: 'bargle'}]},
  {name: 'baz', fields: [{label: 'rar'}, {label: 'hoogah'}]}
],

i = data.findIndex(e => ~e.fields.findIndex(f => f.label == 'rar'));
// returns 1

Upvotes: 0

Paul S.
Paul S.

Reputation: 66404

With arrow functions you can do the searches shown in Mathieu's answer nice and cleanly

let arr = [
  {name: 'foobar', fields: [{label: 'argle'}, {label: 'bargle'}]},
  {name: 'baz', fields: [{label: 'rar'}, {label: 'hoogah'}]}
];

Then

arr.findIndex(item => item.fields.some(deepItem => deepItem.label === 'rar')); // 1

If you're more interested in accessing the item itself, not it's index, then use arr.find instead

arr.find(item => item.fields.some(deepItem => deepItem.label === 'rar')); // Object

Further, if you want every item which matches, then use arr.fileter instead

arr.filter(item => item.fields.some(deepItem => deepItem.label === 'rar')); // [{...}, ...]

Upvotes: 2

Nelson Teixeira
Nelson Teixeira

Reputation: 6610

a 'normal' way of doing it:

var arr = [
  {name: 'foobar', fields: [{label: 'argle'}, {label: 'bargle'}]},
  {name: 'baz', fields: [{label: 'rar'}, {label: 'hoogah'}]},
  {name: 'foo', fields: [{label: 'asjda'}, {label: 'hoogah'}]}
];

function findByLabel(arr, str) {
  var res = null;
  arr.forEach(function(item) { 
      if (item.fields[0].label == 'rar')
          res = item
  });
  return res;
} 

console.log(findByLabel(arr, 'rar'));

Demo: https://jsfiddle.net/5h8ugasf/4/

Upvotes: 0

Mathieu Seiler
Mathieu Seiler

Reputation: 747

You can use the findIndex and some methods of Array.

[
    {name: 'foobar', fields: [{label: 'argle'}, {label: 'bargle'}]},
    {name: 'baz', fields: [{label: 'rar'}, {label: 'hoogah'}]}
].findIndex(function(element, index, array) {
   return element.fields.some(function(element, index, array) {
     return element.label === 'rar';
   });
})

returns 1

Upvotes: 5

Related Questions