【问题标题】:Programmatically find specific node and add property to deep nested object [duplicate]以编程方式查找特定节点并将属性添加到深层嵌套对象[重复]
【发布时间】:2022-01-05 13:38:22
【问题描述】:

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

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

如何只知道值 'deepLevel' 将属性添加到第三层? 我们允许使用 lodash,强烈建议使用 ES6。

最终的dataStructure应该是

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

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

【问题讨论】:

标签: javascript arrays recursion recursive-datastructures


【解决方案1】:

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

这样一个例如可以实现两种方法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; }

【讨论】:

  • 如果我无法知道研究项目的深度怎么办?我给你的答案竖起大拇指:) 回答。
  • @Legeo ... 上述recursivelyFindItemByEntry 的实现与任何嵌套级别无关。除了确定它永远不会违反递归数据结构外,不需要知道任何关于对象的信息。此外,需要知道查询任务在第一个匹配的键值对处停止。因此,在嵌套更深的相等条目的情况下,它们中的任何一个都会被跳过。
猜你喜欢
  • 2020-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-18
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多