0

Let's suppose I have an array like this:

const arr = [
  [
    [
      {name: 'Bob'},
      {name: 'John'},
    ],
    [
      {name: 'Maria'},
      {name: 'Marin'},
      {name: 'Marix'},
      {name: 'Alex'}
    ],
  ],
  [
    [
      {name: 'JP'},
      {name: 'Dox'},
      {name: 'Dor'},
      {name: 'Dog'},
    ],
    [
      {name: 'Dol'},
      {name: 'Fol'},
      {name: 'Fol'},
      {name: 'Fol'}
    ],
  ]
];

I have a name and I want to find the index on the object in the array.

There is my solution it works but I want to find another solution without 3 forEach.

const givenName = 'Dox';
let myIndex;
arr.forEach((firstDepth) => {
  if (firstDepth && Array.isArray(firstDepth)) {
    firstDepth.forEach((secondDepth, i) => {
       secondDepth.forEach((lastStep) => {
        if (lastStep) {
          const { name } = lastStep;
          if (name === givenName) {
             myIndex = i;
          }
        }
      });
    });
  }
});

Thanks.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
maxypayne
  • 3
  • 4

4 Answers4

0

You could take a recursive approach and store the indices for each level as return value.

const
    find = (array, name) => {
        var indices ;
        array.some((item, i) => {
            if (Array.isArray(item)) {
                var temp = find(item, name);
                if (temp) return indices = [i, ...temp];
                return false;
            } 
            if (item.name === name) return indices = [i];
        });
        return indices;
    },
    array = [[[{ name: 'Bob' }, { name: 'John' }], [{ name: 'Maria' }, { name: 'Marin' }, { name: 'Marix' }, { name: 'Alex' }]], [[{ name: 'JP' }, { name: 'Dox' }, { name: 'Dor' }, { name: 'Dog' }], [{ name: 'Dol' }, { name: 'Fol' }, { name: 'Fol' }, { name: 'Fol' }]]];

console.log(find(array, 'Dox'));
console.log(find(array, 'foo'));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

Thanks for your question. 3-Dimensional Arrays are interesting :)

You can use the JavaScript Method filter to avoid redundant forEach loops.

Here's my answer:

const arr = [
  [
    [
      {name: 'Bob'},
      {name: 'John'},
    ],
    [
      {name: 'Maria'},
      {name: 'Marin'},
      {name: 'Marix'},
      {name: 'Alex'}
    ],
  ],
  [
    [
      {name: 'JP'},
      {name: 'Dox'},
      {name: 'Dor'},
      {name: 'Dog'},
    ],
    [
      {name: 'Dol'},
      {name: 'Fol'},
      {name: 'Fol'},
      {name: 'Fol'}
    ],
  ]
];

const givenName = 'Dox';
let myIndex;

_ = arr.filter(firstDepthArray => {
  firstDepthArray.filter(secondDepthArray => {
    secondDepthArray.filter((thirdDepthObject, i) => {
      let name = thirdDepthObject.name;
      if (name === givenName) {
        myIndex = i;
        console.log("Found Index: " + myIndex + " for Element: " + name);
        return;
      }
    })
  })
});

Regards,

AJ

AJ7
  • 129
  • 1
  • 1
  • 7
0

Hello I also tried with recursive approach.

findItem(array, name) {
    array.forEach((item, index) => {
      if (Array.isArray(item)) {
        this.findItem(item, name);
      } else if (item instanceof Object && item.name === name) {
        console.log(`Found item ${item.name} on index ${index}`);
      }
    });
}

this.findItem(arr, 'Alex');
Patrik Dendis
  • 313
  • 6
  • 20
0

What if one name exists more than once? I think you want a list of indexes for every "secondDepth" -Array that contains the name.

Take a look at JS Array-Methods if u trying to shorten your code. For example you can use a combination of map, findIndex() and some() here:

const arr = [[[{name: 'Bob'}, {name: 'John'}],[{name: 'Maria'}, {name: 'Marin'}, {name: 'Marix'}, {name: 'Alex'}]], [[{name: 'JP'}, {name: 'Dox'}, {name: 'Dor'}, {name: 'Dog'}], [{name: 'Dol'}, {name: 'Fol'}, {name: 'Fol'}, {name: 'Fol'}]]];

const givenName = 'Dox';
const myIndexes = arr.map(secondDepth => Array.isArray(secondDepth) 
    ? secondDepth.findIndex(thirdDepth => thirdDepth.some(({name}) => name === givenName))
    : false
  )
  .filter(i => i >= 0)

console.log(myIndexes);
Mischa
  • 1,591
  • 9
  • 14