从参数创建多级对象作为字符串

时间:2016-06-25 21:21:25

标签: javascript

我有一个这样的对象:

{
  "root.apple.color": "red",
  "root.apple.shape": "circle",
  "root.peach[0].color": "green",
  "root.peach[1].color": "yellow",
}

如何将其转换为这样的对象:

{
  "root": {
    "apple": {
      "color": "red",
      "shape": "circle"
    },
    "peach": [
      {
        "color": "green" 
      },
      {
        "color": "yellow" 
      }
    ]
  }
}

基本上我需要一个函数,它将任何数组定义为顶级示例转换为具有真实参数的多级对象。

3 个答案:

答案 0 :(得分:1)

使用Object.keysString.splitArray.isArrayArray.forEach函数的扩展解决方案:

var obj = {
  "root.apple.color": "red",
  "root.apple.shape": "circle",
  "root.peach[0].color": "green",
  "root.peach[0].shape": "square",
  "root.peach[1].color": "yellow",
  "root.apple.info.items[0].type": "text",
  "root.apple.info.items[0].active": true,
  "root.apple.info.items[1].type": "image",
  "root.apple.info.items[1].active": false,
  "root.apple.exterior.toggle[0].id": "left",
  "root.apple.exterior.toggle[0].content": "Ext",
  "root.test": "testing"
},
    result = {};

function transformObject(obj, result) {
    var current,
        checkProp = function (prop, objItem, is_array, idx, val) {
            if (Array.isArray(current) && val) {
                if (typeof idx === 'number' && current[idx]){
                    current[idx][prop] = val;
                } else {
                    var o = {};
                    o[prop] = val;
                    current.push(o);
                }
                
            } else {
                objItem[prop] = objItem[prop] || ((!is_array) ? {} : []);
                if (val) objItem[prop] = val;
                current = objItem[prop];
            }  
        }, 
            re = /\[(\d)\]$/;

    Object.keys(obj).forEach(function (k) {
        var props = k.split("."),
            lastKey = props.length - 1,
            val = obj[k], idx;

        props.forEach(function (prop, k) {
            var is_array = re.test(prop);
            if (is_array) { idx = +prop.match(re)[1]; prop = prop.replace(re, ""); };
            
            checkProp(prop, (!current) ? result : current, is_array, idx, (k === lastKey) ? val : null);
        });
        current = null;
    });

    return result;
}

console.log(JSON.stringify(transformObject(obj, result), 0, 4));

答案 1 :(得分:0)

此实现仅适用于对象嵌套。你可以自己添加阵列感知。



function nested(obj, strPropertyChain, value) {
  var props = strPropertyChain.split('.');
  var len = props.length;
  var o = obj[props[0]] = (obj[props[0]] || {});
  props.slice(1, len - 1)
    .forEach(prop => o = (o[prop] = {}));

  o[props[len - 1]] = value;
  return obj;
}

var obj1 = {
  "root.apple.color": "red",
  "root.apple.shape": "circle",
  "root.peach.color": "green",
  "root.pear.color": "yellow",
}

var obj2 = {}

Object.keys(obj1).forEach(k => nested(obj2, k, obj1[k]));

console.log(obj2);




答案 2 :(得分:0)

你可以这样做;



Object.prototype.setNestedValue = function(...a) {
  a.length > 2 ? typeof this[a[0]] === "object" && this[a[0]] !== null ? this[a[0]].setNestedValue(...a.slice(1))
                                                                       : (this[a[0]] = isNaN(a[1]) ? {} : new Array(a[1]),
                                                                         this[a[0]].setNestedValue(...a.slice(1)))
               : this[a[0]] = a[1];
  return this;
};
var data = {
  "root.apple.color": "red",
  "root.apple.shape": "circle",
  "root.peach[0].color": "green",
  "root.peach[1].color": "yellow",
},
      ok = Object.keys(data),
       o = ok.reduce((o,k) => o.setNestedValue(...k.replace("[",".").replace("]","").split(".").concat(data[k])),{});
console.log(JSON.stringify(o));




Object.prototype.setNestedValue()接受一系列参数,其中最后一个是值,而前一个是,如果字符串类型是嵌套对象属性,或者是整数,数组索引。我不得不将你的对象键变成像"root.peach[0].color": "green" - >这样的数组。 ["root, "peach", "0", "color", "green"]。然后Object.prototype.setNestedValue()会告诉" 0"实际上是一个数组索引。