joputy
joputy

Reputation: 3

How to map() on nested array in a clear way

Newbie here. Please review the following piece of code and suggest how would you write it in a more clear way, because as a newbie, all my ways are way more procedural etc.

  arr.map((p) =>
    p.id === pId
      ? p.bList.map((b) =>
          b.id === bId
            ? b.fList.map((f) =>
                f.id === fId ? console.log('magic happens here') : f
              )
            : b
        )
      : p
  );

I didn't put real names in purpose, so you could see how unreadable it is and very confusing to understand what is going on.

Update: I'm trying to run an operation(get data/modify/delete etc) on a nested array. I'm using Immer, so I actually don't need to take care of mutating the original data, so there's no specific reason to use map() for example.

Update2: Here is an example of the array I have:

    const arr = [
        {
          id: 123,
          // data,
          bList: [
            {
              id: 24,
              // data,
              fList: [
                {
                  id: 51,
                  // data,
                }
              ]
            }
          ]
        },
      ]

So at the above example, I try to modify the fList object that match id 51

Upvotes: 0

Views: 91

Answers (2)

secan
secan

Reputation: 2679

If I got it right, you want to modify an object deeply nested in your array. In this case, you can chain a series of Array.prototype.find() using optional chaining (?.) and do something like:

const itemToUpdate = arr.find(p => p.id === pId)?.
    bList.find(b => b.id === bId)?.
    fList.find(f => f.id === fId)

if (itemToUpdate) {
    console.log('magic happens here')
}

Demo:

const arr = [{
    id: 'foo',
    bList: [{
      id: 'bar',
      fList: [{
          id: 'baz',
          key: 'value'
        },
        {
          id: 'baz2',
          key: 'value'
        }
      ]
    }]
  },
  {
    id: 'goo',
    bList: [{
      id: 'car',
      fList: [{
          id: 'caz',
          key: 'value'
        },
        {
          id: 'caz2',
          key: 'value'
        }
      ]
    }]
  }
]

const pId = 'foo';
const bId = 'bar';
const fId = 'baz';

const itemToUpdate = arr.find(p => p.id === pId)?.
  bList.find(b => b.id === bId)?.
  fList.find(f => f.id === fId);

if (itemToUpdate) {
  itemToUpdate.key = 'new value'
}

console.log(arr);

Upvotes: 0

Jürgen
Jürgen

Reputation: 148

You should chain it with a pipeline. For example like this:

  arr
 .filter(p => p.id === pId)
 .flatMap(p => p.bList)
 .filter(b => b.id === bId)
 .forEach(elm => console.log(elm))

Upvotes: 2

Related Questions