我正在尝试构建一个可以扩展对象的函数,例如:
{
'ab.cd.e' : 'foo',
'ab.cd.f' : 'bar',
'ab.g' : 'foo2'
}
进入嵌套对象:
{ab: {cd: {e:'foo', f:'bar'}, g:'foo2'}}
像这个 php 函数:Set::expand()
当然不使用 eval 。
我正在尝试构建一个可以扩展对象的函数,例如:
{
'ab.cd.e' : 'foo',
'ab.cd.f' : 'bar',
'ab.g' : 'foo2'
}
进入嵌套对象:
{ab: {cd: {e:'foo', f:'bar'}, g:'foo2'}}
像这个 php 函数:Set::expand()
当然不使用 eval 。
我相信这就是你所追求的:
function deepen(obj) {
const result = {};
// For each object path (property key) in the object
for (const objectPath in obj) {
// Split path into component parts
const parts = objectPath.split('.');
// Create sub-objects along path as needed
let target = result;
while (parts.length > 1) {
const part = parts.shift();
target = target[part] = target[part] || {};
}
// Set value at end of path
target[parts[0]] = obj[objectPath]
}
return result;
}
// For example ...
console.log(deepen({
'ab.cd.e': 'foo',
'ab.cd.f': 'bar',
'ab.g': 'foo2'
}));
如果您使用的是 Node.js(例如 - 如果没有从我们的module中剪切和粘贴),请尝试这个包:https : //www.npmjs.org/package/dataobject-parser
构建了一个执行正向/反向操作的module:
https://github.com/Gigzolo/dataobject-parser
它现在被设计为一个自我管理的对象。通过实例化 DataObjectParser 的实例使用。
var structured = DataObjectParser.transpose({
'ab.cd.e' : 'foo',
'ab.cd.f' : 'bar',
'ab.g' : 'foo2'
});
structured.data()
返回您的嵌套对象:
{ab: {cd: {e:'foo', f:'bar'}, g:'foo2'}}
所以这是 JSFiddle 中的一个工作示例:
函数名称很糟糕,代码很快就完成了,但它应该可以工作。请注意,这会修改原始对象,我不确定您是否要创建一个旧对象的扩展版本的新对象。
(function(){
function parseDotNotation( str, val, obj ){
var currentObj = obj,
keys = str.split("."), i, l = keys.length - 1, key;
for( i = 0; i < l; ++i ) {
key = keys[i];
currentObj[key] = currentObj[key] || {};
currentObj = currentObj[key];
}
currentObj[keys[i]] = val;
delete obj[str];
}
Object.expand = function( obj ) {
for( var key in obj ) {
parseDotNotation( key, obj[key], obj );
}
return obj;
};
})();
var expanded = Object.expand({
'ab.cd.e' : 'foo',
'ab.cd.f' : 'bar',
'ab.g' : 'foo2'
});
JSON.stringify( expanded );
//"{"ab":{"cd":{"e":"foo","f":"bar"},"g":"foo2"}}"
源自Esailija 的答案,修复了支持多个顶级键的问题。
(function () {
function parseDotNotation(str, val, obj) {
var currentObj = obj,
keys = str.split("."),
i, l = Math.max(1, keys.length - 1),
key;
for (i = 0; i < l; ++i) {
key = keys[i];
currentObj[key] = currentObj[key] || {};
currentObj = currentObj[key];
}
currentObj[keys[i]] = val;
delete obj[str];
}
Object.expand = function (obj) {
for (var key in obj) {
if (key.indexOf(".") !== -1)
{
parseDotNotation(key, obj[key], obj);
}
}
return obj;
};
})();
var obj = {
"pizza": "that",
"this.other": "that",
"alphabets": [1, 2, 3, 4],
"this.thing.that": "this"
}
输出:
{
"pizza": "that",
"alphabets": [
1,
2,
3,
4
],
"this": {
"other": "that",
"thing": {
"that": "this"
}
}
}
您可以将键字符串拆分为路径,并通过使用未访问级别的默认对象来减少它以分配值。
function setValue(object, path, value) {
var keys = path.split('.'),
last = keys.pop();
keys.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value;
return object;
}
var source = { 'ab.cd.e': 'foo', 'ab.cd.f': 'bar', 'ab.g': 'foo2' },
target = Object
.entries(source)
.reduce((o, [k, v]) => setValue(o, k, v), {});
console.log(target);