如何使用lodash将键值对添加到树结构对象

时间:2019-06-22 10:15:20

标签: javascript arrays lodash

我需要像json对象一样在树的末尾添加键值对。

[{
    "name": "minpur",
    "children": [{
        "name": "ppp1",
        "children": [{
            "name": "feeder",
            "children": [{
                "name": "rmu16",
                "children": [{
                    "name": "invt16",
                    "children": [{
                        "aname": "inv 01"
                    }]
                }]
            }]
        }]
    }]
}]

预期

[{
  "name": "minpur",
  "children": [{
    "name": "ppp1",
    "children": [{
      "name": "feeder",
      "children": [{
        "name": "rmu16",
        "children": [{
          "name": "invt16",
          "children": [{
            "aname": "inv 01",
            **
            "value": 300 **
          }]
        }]
      }]
    }]
  }]
}]

尝试以下递归函数

let traverse = function(jsonObj) {
  if (jsonObj !== null && typeof jsonObj == "object") {
    return Object.entries(jsonObj).forEach(([key, value]) => {
      if (key != "aname") {
        traverse(value);
      } else {
        return value;
      }
    });
  }
}

4 个答案:

答案 0 :(得分:1)

检查对象上是否存在aname键,并添加该属性。如果它不能用Array.forEach()遍历子代,并在子代上遍历。

const traverse = (key, value) => obj => {
  const inner = obj => {
    if(obj.hasOwnProperty(key)) obj.value = value
    else obj.children.forEach(inner)
  }
  
  return inner(obj)
}

const tree = [{"name":"minpur","children":[{"name":"ppp1","children":[{"name":"feeder","children":[{"name":"rmu16","children":[{"name":"invt16","children":[{"aname":"inv 01"}]}]}]}]}]}]

tree.forEach(traverse('aname', 300))

console.log(tree)

答案 1 :(得分:0)

这是一个更实用的解决方案,其中原始值保持不变。 检查了子节点,如果没有子节点,则使用传递的键来扩展当前节点。

const obj = [{
  "name": "minpur",
  "children": [{
    "name": "ppp1",
    "children": [{
      "name": "feeder",
      "children": [{
        "name": "rmu16",
        "children": [{
          "name": "invt16",
          "children": [{
            "aname": "inv 01"
          }]
        }]
      }]
    }]
  }]
}]

function addToLeaf(append, node) {
  if (!node.children) {
    return {
      ...node,
      ...append
    }
  }
  return { 
    ...node,
    ...{ children: node.children.map(child => addToLeaf(append, child))}
  }
}

const result = obj.map((node) => addToLeaf({
  value: 300
}, node));

console.log(result);

答案 2 :(得分:0)

如果您想使用JS实用程序库lodash,它将为您提供许多处理此类复杂结构的方法。

为此,我建议使用_.set-https://lodash.com/docs/4.17.11#set

const _u = _.noConflict(); 
var object = { 'a': [{ 'b': { 'c': 3 } }] };
 
_u.set(object, 'a[0].b.c', 4);
console.log(object);
// => 4
 
_u.set(object, ['x', '0', 'y', 'z'], 5);
console.log(object);
// => 5
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

答案 3 :(得分:0)

您可以创建一个递归函数,该递归函数遍历对象数组,并将找到的对象(由指定的key name与您指定的参数合并。需要No lodash

let data = [{ "name": "minpur", "children": [{ "name": "ppp1", "children": [{ "name": "feeder", "children": [{ "name": "rmu16", "children": [{ "name": "invt16", "children": [{ "aname": "inv 01" }] }] }] }] }] }]

let deepSetByKey = (a, k, setObj) =>
  a.forEach(o => k in o ? Object.assign(o, setObj) : 
   'children' in o ? deepSetByKey(o.children, k, setObj) : 0) && a

deepSetByKey(data, 'aname', { value: 300 }) // call the fn

console.log(data[0].children[0].children[0].children[0].children[0].children[0])

这个想法是要在Array.forEach中进行递归遍历,并在当前对象中找到所需的道具时使用Object.assign