[英]Dynamically creating objects with array of paths in dot notation
I was wondering if it is possible to dynamically generate an object with an array of strings in dot notation. 我想知道是否可以用点表示法动态生成带有字符串数组的对象。 I would like to dynamically build a JSON object from a CSV file.
我想从CSV文件动态构建JSON对象。 The goal is to build the CSV as JSON, then filter the properties and make a new JSON object.
目标是将CSV构建为JSON,然后过滤属性并创建新的JSON对象。
So I would like to pass in something like this.. 所以我想传递这样的东西..
var obj = {};
var keyArray = ['meta', 'logos', 'warranty', 'specs', 'specs.engine', 'specs.engine.hp', 'specs.engine.rpm', 'specs.engine.manufacturer'];
The end result would be something like this... 最终结果将是这样的......
obj = {
meta: {
},
logos: {
},
specs: {
engine: {
hp: {
}
}
}
}
Here is the main function 这是主要功能
function addObjectsByKey(obj, keyArray) {
for (var key in keyArray) {
// If keyword is not in object notation
if (!(keyArray[key].match(/\./))) {
// If the object property is not set, set it
if (!(obj[keyArray[key]])) {
obj[keyArray[key]] = {};
}
} else {
// Split array element (in dot notation) into an array of strings
// These strings will be object properties
var pathAsArray = keyArray[key].split('.');
var path = null;
for (var k in pathAsArray) {
if (path == null) {
obj[pathAsArray[k]] = {};
path = pathAsArray[k];
} else {
obj[path][pathAsArray[k]] = {};
path += '.' + pathAsArray[k];
}
}
// throw Error('end');
}
}
// return obj;
}
You can use forEach
loop and inside you can split each element on .
您可以使用
forEach
循环,在里面可以拆分每个元素.
and then use reduce
method to build nested object. 然后使用
reduce
方法构建嵌套对象。
var keyArray = ['meta', 'logos', 'warranty', 'specs', 'specs.engine', 'specs.engine.hp', 'specs.engine.rpm', 'specs.engine.manufacturer']; const result = {} keyArray.forEach(key => { // Loop array of keys // Split each key with . and use reduce on that // In each iteration of reduce return r[e] which is going to be value if property exists // or new object if it doesn't // This way you can go to any object depth as long as keys match existing keys in object. key.split('.').reduce((r, e) => r[e] = (r[e] || {}), result) }) console.log(result)
Here is another approach using for
loops that will return the same result. 这是使用
for
循环的另一种方法,它将返回相同的结果。
var keyArray = ['meta', 'logos', 'warranty', 'specs', 'specs.engine', 'specs.engine.hp', 'specs.engine.rpm', 'specs.engine.manufacturer' ]; const result = {} for(var i = 0; i < keyArray.length; i++) { const keys = keyArray[i].split('.'); let ref = result; for(var j = 0; j < keys.length; j++) { const key = keys[j]; if(!ref[key]) ref[key] = {} ref = ref[key] } } console.log(result)
You can use the function reduce
along with a nested forEach
to build the path. 您可以使用函数
reduce
和嵌套的forEach
来构建路径。
reduce
will accumulate the nested operation. reduce
将累积嵌套操作。 forEach
will build the object and its children according to the current path separated by dots. forEach
将根据以点分隔的当前路径构建对象及其子对象。 let keyArray = ['meta', 'logos', 'warranty', 'specs', 'specs.engine', 'specs.engine.hp', 'specs.engine.rpm', 'specs.engine.manufacturer'], newObj = keyArray.reduce((accum, path) => { let previous = accum; path.split('.').forEach(key => { if (previous[key]) previous = previous[key]; else previous = previous[key] = {}; }); return accum; }, {}); console.log(newObj);
.as-console-wrapper { max-height: 100% !important; top: 0; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.