Javascript 使用 lodash 展平嵌套对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42645376/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
flatten nested object using lodash
提问by Giala Jefferson
flatten, flattenDeep or flattenDepth of lodash only accept array. How to flatten nested object?
lodash 的 flatten、flattenDeep 或 flattenDepth 只接受数组。如何展平嵌套对象?
var data = {
"dates": {
"expiry_date": "30 sep 2018",
"available": "30 sep 2017",
"min_contract_period": [{
"id": 1,
"name": "1 month",
"value": false
}, {
"id": 2,
"name": "2 months",
"value": true
}, {
"id": 3,
"name": "3 months",
"value": false
}]
},
"price": {
"curreny": "RM",
"min": 1500,
"max": 2000
}
}
I want nested property to be the first level, like expiry_date should be level 1, not within dates, and I think dates should be gone, it's not needed anymore. I can do it manually, use map() but I'm looking to use lodash to ease the task.
我希望嵌套属性是第一级,比如 expiry_date 应该是 1 级,而不是在日期内,我认为日期应该消失,不再需要了。我可以手动完成,使用 map() 但我希望使用 lodash 来简化任务。
回答by RaR
One of the easiest solutions would be, merging the nested object with parent,
最简单的解决方案之一是,将嵌套对象与父对象合并,
_.merge(data, data.dates);
This will bring all data.datesproperty into data. Then delete data.dates
这会将所有data.dates属性带入data. 然后删除data.dates
delete data.dates
回答by T.Chmelevskij
ES6 version:
ES6版本:
var data = {
"dates": {
"expiry_date": "30 sep 2018",
"available": "30 sep 2017",
"min_contract_period": [{
"id": 1,
"name": "1 month",
"value": false
}, {
"id": 2,
"name": "2 months",
"value": true
}, {
"id": 3,
"name": "3 months",
"value": false
}]
},
"price": {
"curreny": "RM",
"min": 1500,
"max": 2000
}
};
var {dates: {expiry_date, ...dates}, ...rest} = data;
var flatData = {dates, expiry_date, ...rest}
console.log(flatData)
One thing to note is that you have to be careful with deeply nested destructuting. In this example if data.datesis undefinedand you'll try to destructure it, error will be thrown.
需要注意的一件事是,您必须小心深度嵌套的解构。在这个例子中,如果data.dates是undefined并且你将尝试解构它,则会抛出错误。
回答by Yosvel Quintero Arguelles
You can .merge()the result of .get()and _.pick():
var data = {"dates": {"expiry_date": "30 sep 2018","available": "30 sep 2017","min_contract_period": [{"id": 1,"name": "1 month","value": false}, {"id": 2,"name": "2 months","value": true}, {"id": 3,"name": "3 months","value": false}]},"price": {"curreny": "RM","min": 1500,"max": 2000}},
result = _.merge(_.get(data, 'dates'), _.pick(data, 'price'));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
回答by Andrey
this flattens object with nested objects and arrays of any depth. keys in resulting object are full paths to properties in input object
这会使用嵌套对象和任何深度的数组来展平对象。结果对象中的键是输入对象中属性的完整路径
public static flattenObject(o: any, prefix?: string, result?: any): any {
prefix = prefix ? prefix : '';
result = result ? result : {};
if (_.isString(o) || _.isNumber(o) || _.isBoolean(o)) {
result[prefix] = o;
return result;
}
if (_.isArray(o) || _.isPlainObject(o)) {
for (let i in o) {
let pref = prefix;
if (_.isArray(o)) {
pref = pref + `[${i}]`;
} else {
if (_.isEmpty(prefix)) {
pref = i;
} else {
pref = prefix + '.' + i;
}
}
Utils.flattenObject(o[i], pref, result);
}
return result;
}
return result;
}
回答by Vincent
function flattenObject(o, prefix = '', result = {}, keepNull = true) {
if (_.isString(o) || _.isNumber(o) || _.isBoolean(o) || (keepNull && _.isNull(o))) {
result[prefix] = o;
return result;
}
if (_.isArray(o) || _.isPlainObject(o)) {
for (let i in o) {
let pref = prefix;
if (_.isArray(o)) {
pref = pref + `[${i}]`;
} else {
if (_.isEmpty(prefix)) {
pref = i;
} else {
pref = prefix + '.' + i;
}
}
flattenObject(o[i], pref, result, keepNull);
}
return result;
}
return result;
}

