2016-08-04 211 views
0

我有一个要求圆点分隔的键,我有一个对象像obj={ 'a.b.c' : d } JavaScript对象,我想它转换为:{a:{b:{c:d}}}创建从在另一个对象

有什么办法,我可以做到这一点在JavaScript中?

+0

有没有这样的对象'{ABC:d} '。这是无效的语法。 – 2016-08-04 13:54:09

+0

@torazaburo如果你使用'obj [key]'语法创建一个空对象并设置属性,这是完全有效的,尽管我不明白为什么。如果在对象声明过程中将键设置为字符串,它也可以工作。 – kag359six

+0

@ kag359six然后,OP应该修正他的问题,将它设置为一个字符串,就像现在这样,它是无效的语法。 – 2016-08-04 14:03:19

回答

0

这里有一个解决方案(编辑:代码比以前更复杂,但是它给你想要的结果,让我知道,如果事情不工作):

var obj = { 
 
    'a.b.c': 22, 
 
    'a.b.d.e': 42 
 
} 
 

 
var newObj = {}; 
 

 
for (var key in obj) { 
 

 
    if (obj.hasOwnProperty(key)) { 
 

 
     var keyList = key.split('.'); 
 
     newObj = generateNewObject(keyList, keyList.length - 1, newObj, obj[key]); 
 

 
    } 
 

 
} 
 

 
console.log(newObj); 
 

 
function generateNewObject(keys, index, existingObj, value) { 
 

 
    if (index < 0) { 
 
     return value; 
 
    } 
 

 
    var lastKey = keys[index--]; 
 
    var existingProperty = getProperty(existingObj, lastKey); 
 

 
    if (existingProperty != null && !objectsAreEqual(existingProperty, value)) { 
 

 
     var valueKey = keys[index + 2]; 
 
     existingProperty[lastKey][valueKey] = value[valueKey]; 
 
     value = existingProperty; 
 

 

 
    } else { 
 

 
     var subObj = {}; 
 
     subObj[lastKey] = value; 
 
     value = subObj; 
 
    } 
 

 
    return generateNewObject(keys, index, existingObj, value); 
 

 
} 
 

 
function objectsAreEqual(obj1, obj2) { 
 

 
    for (var key in obj1) { 
 

 
     if (obj1.hasOwnProperty(key)) { 
 

 
      var prop = getProperty(obj2, key); 
 
      if (prop == null) { 
 
       return false; 
 
      } 
 

 
     } 
 

 
    } 
 

 
    return true; 
 

 
} 
 

 
function getProperty(obj, keyDesired) { 
 

 
    for (var key in obj) { 
 

 
     if (obj.hasOwnProperty(key)) { 
 

 
      if (key === keyDesired) { 
 

 
       return obj; 
 

 
      } else { 
 

 
       var prop = getProperty(obj[key], keyDesired); 
 

 
       if (prop != null) { 
 
        return prop; 
 
       } 
 

 
      } 
 

 
     } 
 

 
    } 
 

 
    return null; 
 

 
}

我不知道为什么你会有一个这样命名的对象,但是这段代码会为对象中的每个键做诀窍。这在嵌套对象(如{'a' : { 'b' { 'c' : {{'d' : 'e'}}}}})上无法正常工作。每次该值为JavaScript对象时,您都必须重复执行for循环部分。

EDIT

我修改代码,以便能够识别当两个属性是例如相同的例子{ 'a.b.c' : 22 }, 'a.b.c.d.e' : 42。对不起,如果很难通过,但基本上generateNewObject方法是真正的肉。它下面的两个函数只是辅助方法。

+0

他不希望'{'abc':22,'abd':42}'产生'{a:{b:{c:22,d:42}}} ? – 2016-08-04 14:09:48

+0

是的我想要你在说什么torazaburo – user1835326

+0

@ kag359six感谢您的答案。它是有益的。但如果什么建议torazaburo是可能的,那么它将是完美的 – user1835326

0

Array.reduce对于更复杂的数据结构的处理/转换大多是一个不错的选择。这一般解决给定的问题,同时考虑极端情况考虑那么可能类似于下一提供的示例的方法...

var 
 
    d = 'd', 
 
    q = 'q', 
 

 
    obj = { 
 
     'i.k.l.m.n.o.p' : q, 
 
     'a.b.c'   : d, 
 
     'foo'   : 'bar', 
 
     ''    : 'empty' 
 
    }; 
 

 
function parseIntoNestedTypes(type) { 
 
    return Object.keys(type).reduce(function (collector, integralKey) { 
 

 
     var 
 
      nestedType   = collector.target, 
 
      fragmentedKeyList = integralKey.split('.'), 
 
      nestedTypeRootKey = fragmentedKeyList.shift(), 
 
      nestedTypeEndValue = collector.source[integralKey]; 
 

 
     if (fragmentedKeyList.length === 0) { 
 

 
      nestedType[nestedTypeRootKey] = nestedTypeEndValue; 
 
     } else { 
 
      nestedType[nestedTypeRootKey] = fragmentedKeyList.reduce(function (collector, key, idx, list) { 
 

 
       var 
 
        partialType = collector.partialType || collector.type; 
 

 
       if (idx < (list.length - 1)) { 
 

 
        partialType[key] = {}; 
 
       } else { 
 
        partialType[key] = collector.value; 
 
       } 
 
       collector.partialType = partialType[key]; 
 

 
       return collector; 
 

 
      }, { 
 

 
       value : nestedTypeEndValue, 
 
       type : {} 
 

 
      }).type; 
 
     } 
 
     return collector; 
 

 
    }, { 
 

 
     source: type, 
 
     target: {} 
 

 
    }).target; 
 
} 
 

 
console.log('parseIntoNestedTypes :: type', JSON.stringify(obj)); 
 
console.log('parseIntoNestedTypes :: nestedType', JSON.stringify(parseIntoNestedTypes(obj))); 
 

 
console.log('parseIntoNestedTypes :: type, nestedType : ', obj, parseIntoNestedTypes(obj));

相关问题