Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lodash recursively find item in array

What might be the easiest solution in lodash to recursively find item in array by, for example, 'text' field with value 'Item-1-5-2'?

const data = [
      {
        id: 1,
        text: 'Item-1',
        children: [
          { id: 11, text: 'Item-1-1' },
          { id: 12, text: 'Item-1-2' },
          { id: 13, text: 'Item-1-3' },
          { id: 14, text: 'Item-1-4' },
          {
            id: 15,
            text: 'Item-1-5',
            children: [
              { id: 151, text: 'Item-1-5-1' },
              { id: 152, text: 'Item-1-5-2' },
              { id: 153, text: 'Item-1-5-3' },
            ]
          },
        ]
      },
      {
        id: 2,
        text: 'Item-2',
        children: [
          { id: 21, text: 'Item-2-1' },
          { id: 22, text: 'Item-2-2' },
          { id: 23, text: 'Item-2-3' },
          { id: 24, text: 'Item-2-4' },
          { id: 25, text: 'Item-2-5' },
        ]
      },
      { id: 3, text: 'Item-3' },
      { id: 4, text: 'Item-4' },
      { id: 5, text: 'Item-5' },
    ];

Thank You!

like image 559
shkipper Avatar asked Oct 06 '16 12:10

shkipper


2 Answers

In plain Javascript, you could use Array#some recursively.

function getObject(array, key, value) {
    var o;
    array.some(function iter(a) {
        if (a[key] === value) {
            o = a;
            return true;
        }
        return Array.isArray(a.children) && a.children.some(iter);
    });
    return o;
}

var data = [{ id: 1, text: 'Item-1', children: [{ id: 11, text: 'Item-1-1' }, { id: 12, text: 'Item-1-2' }, { id: 13, text: 'Item-1-3' }, { id: 14, text: 'Item-1-4' }, { id: 15, text: 'Item-1-5', children: [{ id: 151, text: 'Item-1-5-1' }, { id: 152, text: 'Item-1-5-2' }, { id: 153, text: 'Item-1-5-3' }, ] }, ] }, { id: 2, text: 'Item-2', children: [{ id: 21, text: 'Item-2-1' }, { id: 22, text: 'Item-2-2' }, { id: 23, text: 'Item-2-3' }, { id: 24, text: 'Item-2-4' }, { id: 25, text: 'Item-2-5' }, ] }, { id: 3, text: 'Item-3' }, { id: 4, text: 'Item-4' }, { id: 5, text: 'Item-5' }, ];

console.log(getObject(data, 'text', 'Item-1-5-2'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 157
Nina Scholz Avatar answered Nov 03 '22 21:11

Nina Scholz


It's the perfect spot for a recursive function.

function findText(items, text) {
  if (!items) { return; }

  for (const item of items) {
    // Test current object
    if (item.text === text) { return item; }

    // Test children recursively
    const child = findText(item.children, text);
    if (child) { return child; }
  }
}

That's also the best way to get the maximum performances. Traversal is some in depth-first-search way.

like image 35
Aurelien Ribon Avatar answered Nov 03 '22 19:11

Aurelien Ribon