以编程方式查找特定节点并将 属性 添加到深层嵌套对象

Programmatically find specific node and add property to deep nested object

给定一个像这样的数组,其中最大深度可以是 3 个级别,而我们不知道研究项目可能在哪个级别:

const data = {
         id: '1',
         children: [
             {
               id: '2',
               name: 'nameTest',
               children: [
                     {
                       id: '3'
                       name: 'deepLevel'
                      }
                ]
              }
          }

如何在只知道值 'deepLevel' 的情况下将 属性 添加到第三层? 我们被允许使用 lodash 并强烈建议使用 ES6。

最终的数据结构应该是

给定一个像这样的数组,其中最大深度可以是 3 层:

const data = {
         id: '1',
         children: [
             {
               id: '2',
               name: 'nameTest',
               children: [
                     {
                       id: '3'
                       name: 'deepLevel'
                       addedProperty: true,
                      }
                ]
              }
        }

一种方法是通过自定义(可定制)条目(键值对)将查找嵌套项目的任务分开,并将额外的自定义数据分配给找到的项目。

因此,例如可以实现两种基于自递归的方法 recursivelyFindItemByEntry 和一个简单的 assignToObjectWithFirstMatchingNestedEntry ,它将提供的数据分配给前一个函数调用的结果 ...

function recursivelyFindItemByEntry(obj, [key, value]) {
  let item;

  if (!!obj && (typeof obj === 'object')) {
    if (
      obj.hasOwnProperty(key) &&
      (obj[key] === value)
    ) {
      item = obj;

    } else if (
      obj.hasOwnProperty('children') &&
      Array.isArray(obj.children)
    ) {
      obj.children.some(child => {

        item = recursivelyFindItemByEntry(child, [key, value]);
        return !!item;
      });
    }
  }
  return item;
}

function assignToObjectWithFirstMatchingNestedEntry(obj, [key, value], data) {
  Object.assign(
    recursivelyFindItemByEntry(obj, [key, value]) ?? {},
    data ?? {}
  );
  return obj;
}

const data = {
  id: '1',
  children: [{
    id: '2',
    name: 'nameTest',
    children: [{
      id: '3',
      name: 'deepLevel',
    }, {
      id: '4',
      name: 'deepLevel',
    }],
  }, {
    id: '5',
    name: 'nameTest',
    children: [{
      id: '6',
      name: 'deepLevel',
    }, {
      id: '7',
      name: 'deepLevelTarget',
      // addedProperty: true,
    }, {
      id: '8',
      name: 'deepLevel',
    }],
  }, {
    id: '9',
    name: 'nameTest'
  }, {
    id: '10',
    name: 'nameTestTarget'
  }, {
    id: '11',
    name: 'nameTest'
  }],
};

console.log(
  "recursivelyFindItemByEntry(data, ['name', 'deepLevelTarget']) ...",
  recursivelyFindItemByEntry(data, ['name', 'deepLevelTarget'])
);
console.log(
  "recursivelyFindItemByEntry(data, ['id', '10']) ...",
  recursivelyFindItemByEntry(data, ['id', '10'])
);
console.log('\n');

console.log(
  "recursivelyFindItemByEntry(data, ['id', 'foo']) ...",
  recursivelyFindItemByEntry(data, ['id', 'foo'])
);
console.log(
  "recursivelyFindItemByEntry(data, ['id', '1']) ...",
  recursivelyFindItemByEntry(data, ['id', '1'])
);
console.log('\n');

console.log(
  "assignToObjectWithFirstMatchingNestedEntry(data, ['name', 'deepLevelTarget']), { addedProperty: true } ...",
  assignToObjectWithFirstMatchingNestedEntry(data, ['name', 'deepLevelTarget'], { addedProperty: true })
);
.as-console-wrapper { min-height: 100%!important; top: 0; }