将点分割成单独的对象JavaScript

5

我有一个像这样的对象:

var data = {"prop.health": 1, "prop.cost":1, "prop.time":1}

我想将它转换为如下格式的对象:
{
  "prop": {
    "health": 1, 
    "cost":1, 
    "time":1
  }
}

这是我的代码:

  _.each(data, function (value, key) {
    var split = key.split('.')
    if (split.length > 1) {
      data[split[0]] = data[split[0]] || {}
      data[split[0]][split[1]] = value
      delete data[key]
    }
  })

但这只适用于一层嵌套。你如何编写代码以确保它适用于任何深度的嵌套属性?


2
嵌套长什么样?prop.test.fun - epascarello
1
{'prop':{'test': {'fun': 1}}} - Harry
不确定是否有帮助,但是lodash可以从点符号字符串创建嵌套对象。https://lodash.com/docs#set - AtheistP3ace
但是你为什么要像那样拥有/保存对象呢?如果我问一下,有什么好处吗?只是出于好奇:p - Rens Tillmann
2
@RensTillmann 我以前用过这个方法来保持客户端视图模型与服务器端对象同步,只需将对象路径和值传递给我,然后从服务器端路径更新我的客户端视图模型。 - AtheistP3ace
显示剩余3条评论
3个回答

7
你可以使用 _.transform_.set 的组合。例如:
data = _.transform(data, function(transformed, val, key) {
    _.set(transformed, key, val);
});

结果在

{"prop":{"health":1,"cost":1,"time":1}}

1
没有库的话,代码会像这样:

(function(){
    var data = {"prop.health": 1, "prop.cost":1, "prop.time":1, "prop.test.fun" : 1, "prop.test.sun" : 1};
    var obj = {};  //will hold the object all parsed out
    Object.keys(data).forEach( function (key) {  //loop through the keys in the object
        var val = data[key];  //grab the value of this key
        var step = obj;  //reference the object that holds the values
        key.split(".").forEach(function(part, index, arr){   //split the parts and loop
            if(index===arr.length-1){  //If we are at the last index, than we set the value
                step[part] = val;
            } else if(step[part]===undefined) {  //If we have not seen this key before, create an object
                step[part] = {};
            }
            step = step[part];  //Step up the object we are referencing 
        });
    } );
    console.log(obj);
}());

或者双重减少循环

(function(){
    var data = {"prop.health": 1, "prop.cost":1, "prop.time":1, "prop.test.fun" : 1, "prop.test.sun" : 1};
    var result = Object.keys(data).reduce( function (obj, key) {  //loop through the keys in the object
        var val = data[key];  //grab the value of this key
        key.split(".").reduce(function(step, part, index, arr){   //split the parts and loop
            if(index===arr.length-1){  //If we are at the last index, than we set the value
                step[part] = val;
            } else if(step[part]===undefined) {  //If we have not seen this key before, create an object
                step[part] = {};
            }
            return step[part];  //Step up the object we are referencing
        }, obj);
        return obj;
    }, {});
    console.log(result);
}());


啊哦,没有 Array.prototype.reduce ;) - Phil
哈哈,我现在正在玩一个缩小版的。 :) - epascarello
@Phil 现在满意了吗?可能还有其他的方法可以实现。 :) - epascarello

0

根据多种因素(例如,如果原始对象始终具有要删除的键等),您可以使用{{link1:_.set}}:

var data = {"prop.health": 1, "prop.cost":1, "prop.time":1};

_.each(data, function (value, key) {
  delete data[key];
  _.set(data, key, value);
});

_.set 如果路径不存在,它将创建该路径。以上结果为:

{"prop":{"health":1,"cost":1,"time":1}}

{"prop.health": 1, "prop.cost.food":1, "prop.time":1} 将会得到以下结果:

{"prop":{"health":1,"cost":{"food":1},"time":1}}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接