【问题标题】:Javascript - traverse tree like object and add a keyJavascript - 像对象一样遍历树并添加一个键
【发布时间】:2026-01-27 21:50:01
【问题描述】:

假设我有一个深度为 N 的对象,例如:

food = {
    'Non-Animal': {
        'Plants' : {
            'Vegetables': {
                ...
            }             
        },
            'Minerals' : {
                ...
            }
        },
    'Animal': {
        ...
    }
}

我想在这个对象中添加“水果”类别,但我必须搜索“植物”所在的对象,然后添加它。所以我不想在一个声明中做:

food['Non-Animal']['Plants']['Fruits'] = {};

因为我想先搜索它所属的位置。

如何在迭代对象时将水果类别添加到对象中?到目前为止我所拥有的是:

addCategory(food, category, parent);

function addCategory(obj, category, parent_name) {
    for (var key in obj) {
        if (key == parent_name) {
            obj[key][category] = {};
        }
        var p = obj[key];
        if (typeof p === 'object') {
            addCategory(p, category, parent);
        } else {

        }
    }
}

我怎样才能修复这个例程来做到这一点,或者有更好的方法来做到这一点?

【问题讨论】:

  • 您可以查看this
  • 小心使用typeof p === 'object',因为如果p 是任何类型的对象,例如array,这将是真的。

标签: javascript object


【解决方案1】:

如果我对您的理解正确,我认为您希望您的函数定义一个可变参数,该参数采用您希望遍历的路径的各个名称,并在必要时创建。

为此使用.reduce() 非常容易。

const food = {
  'Non-Animal': {
    'Plants': {
      'Vegetables': {}
    },
    'Minerals': {}
  },
  'Animal': {}
}

console.log(addCategory(food, "Non-Animal", "Plants", "Fruits"));
console.log(addCategory(food, "Non-Animal", "Minerals", "Gold"));

function addCategory(obj, ...path) {
  return path.reduce((curr, name) => {
    if (!curr) return null;
    if (!curr[name]) return (curr[name] = {});
    return curr[name];

    // More terse but perhaps less readable
    // return curr ? curr[name] ? curr[name] : (curr[name]={}) : null; 
  }, obj);  
}

console.log(JSON.stringify(food, null, 2));

【讨论】:

    【解决方案2】:

    看起来不错。但是,您可能希望在添加道具后终止:

    function addCategory(obj, category, parent_name) {
       for (var key in obj) {
          if (key == parent_name){
           return obj[key][category] = {};
          }
          var p = obj[key];
          if (typeof p === 'object') {
            if(addCategory(p, category, parent)) return true;
          } 
      }
    }
    

    【讨论】:

      【解决方案3】:

      我只看到一个错误:递归调用 addCategory 找不到父变量,因为它在您的范围内称为 parent_name。

      var food = {
        'Non-Animal': {
          'Plants' : {
            'Vegetables': {
             }
          },
          'Minerals' : {}
        },
        'Animal': {}
      }
      
      function addCategory(obj, category, parent_name) {
        for (var key in obj) {
          if (key == parent_name){
            obj[key][category] = {};
          }
          var p = obj[key];
          if (typeof p === 'object') {
            addCategory(p, category, parent_name);
          } else {
      
          }
        }
      }
      
      console.log(food);
      addCategory(food, 'Fruits', 'Plants');
      console.log(food);

      【讨论】:

        【解决方案4】:

        您可以使用 reduce 来创建函数,该函数将键作为字符串,将对象作为您想要分配给某个嵌套对象的值。

        var food = {"Non-Animal":{"Plants":{"Vegetables":{}},"Minerals":{}},"Animal":{}}
        
        function add(key, value, object) {
          key.split('.').reduce(function(r, e, i, arr) {
            if(r[e] && i == arr.length - 1) Object.assign(r[e], value);
            return r[e]
          }, object)
        }
        
        add('Non-Animal.Plants', {'Fruits': {}}, food)
        console.log(food)

        【讨论】:

          最近更新 更多