3

I have such object:

var obj = [
    {
      name: 'ob_1',
      childFields: [],
    },
    {
      name: 'ob_2',
      childFields: [
        {
          name: 'ob_2_1',
          childFields: [
            {
              name: 'ob_3_1',
              childFields: [],
              test: 124
            },
          ],
        },
      ],
    },
  ]

function getObjectByNamePath(path, fieds) {
    const pathArr = path.split('.');
    const result = fieds.find(field => {
      if (pathArr.length > 1) {
        if (field.name === pathArr[0] && field.childFields.length) {
          const newPath = pathArr.slice(1, pathArr.length).join('.');
          return getObjectByNamePath(newPath, field.childFields);
        }
        return false;
      } else {
        if (field.name === pathArr[0]) {
            return true;
        } else {
            return false;
        }
      }
    });
    return result;
  }

I want to get object by name values path:

console.log(getObjectByNamePath('ob_2.ob_2_1.ob_3_1', obj))

I tried this, but it doesn't work correct and i feel that there is more elegant way to achieve what i want. Thanks.

justDan
  • 2,302
  • 5
  • 20
  • 29
mr__brainwash
  • 1,334
  • 3
  • 16
  • 40
  • 2
    Possible duplicate of [Accessing nested JavaScript objects with string key](https://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key) – Mitya May 30 '18 at 13:24
  • @Utkanos, not really, because here are arrays for seaching, not only objects. – Nina Scholz May 30 '18 at 13:31

2 Answers2

5

You could iterate the childFields and find the name for this level, then take the next level name.

function getObjectByNamePath(path, array) {
    return path
        .split('.')
        .reduce(
            ({ childFields = [] } = {}, name) => childFields.find(o => o.name === name),
            { childFields: array }
        );
}

var obj = [{ name: 'ob_1', childFields: [], }, { name: 'ob_2', childFields: [ { name: 'ob_2_1', childFields: [ { name: 'ob_3_1', childFields: [], test: 124 }] }] }];

console.log(getObjectByNamePath('ob_2.ob_2_1.ob_3_1', obj));
console.log(getObjectByNamePath('ob_1', obj));
console.log(getObjectByNamePath('foo.bar', obj));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

A recursive solution.

var obj = [{ name: 'ob_1', childFields: [], }, { name: 'ob_2', childFields: [ { name: 'ob_2_1', childFields: [ { name: 'ob_3_1', childFields: [], test: 124 }] }] }]

function getObjectByNamePath(path, obj) {
  const [currentPath, ...restPaths] = path.split('.'); 
  const nextObj = (obj.find(e => e.name === currentPath))
  
  if(!restPaths.length) return nextObj;
  return getObjectByNamePath(restPaths.join('.'), nextObj.childFields || []);
}


// Test Cases
console.log(getObjectByNamePath('ob_2.ob_2_1.ob_3_1', obj))
console.log(getObjectByNamePath('ob_2.ob_2_1.ob_3_1.fakePath', obj))
console.log(getObjectByNamePath('ob_1', obj))
console.log(getObjectByNamePath('', obj))
Ritwick Dey
  • 18,464
  • 3
  • 24
  • 37