如何解决递归如何从具有嵌套对象和数组的对象中获取所有键/值对
我有一个看起来像这样的对象:
{
"id": 45745049
"seller": {
"first_name": "Sam","last_name": "Smith","email": "samsmith@smith.com","phone": {
"number": "1111-1111","verified": false
},},"order_items": [
{
"item": {
"id": "29239765","title": "item1","colors": [
"red","green","blue"
]
},"quantity": 1,"unit_price": 230,{
"item": {
"id": "238457363","title": "item2","colors": [
"red"
]
},"quantity": 2,"unit_price": 110,}
],"date_created": "2020-08-03T12:17:25.000-04:00","date_last_updated": "2020-08-03T16:51:35.61Z"
}
我想要一个在对象中具有每个键值对的数组。
例如:
[
["id",45745049],["first_name","Sam"],.....,["phone.number","1111-1111"],["phone.verified",false],....etc
]
一切正常,直到这一点。问题是属性是对象数组时。我想要的输出如下:
[
...,["order_items1.item.id",29239765],["order_items1.item.colors1","red"],["order_items1.item.colors2","green"],...,["order_items2.item.id",238457363],["order_items2.item.colors1",...etc
]
因此,需要检查属性是否为数组,如果是,则添加位置编号。
我知道我需要递归函数,但我不知道该怎么做。 这就是我到目前为止所得到的。
getObjectKeys = (obj) => {
let FieldName = "";
let FieldValue = "";
for(var prop in obj) {
FieldName += prop;
if(!(prop instanceof Array) && (typeof prop !== "object") && obj[prop]) {
FieldValue = obj[prop];
} else if(prop instanceof Array && prop.length !== 0){
prop.forEach((innerItem,i) => {
FieldName += `${i+1}.`;
// check if the inner item is an array or whatever an do it all again
// Dont know what to do here.
});
} else {
getObjectKeys(obj[prop]);
}
}
return [FieldName,FieldValue];
}
注意:我不要空键或空键。
如果有人可以帮助我,我将不胜感激。还是谢谢你!
解决方法
这与您要查找的内容非常相似。这是一种技术I use often。
const getPaths = (obj) =>
Object (obj) === obj
? Object .entries (obj) .flatMap (([k,v]) => getPaths (v) .map (p => [k,... p]))
: [[]]
const path = (ps) => (obj) =>
ps .reduce ((o,p) => (o || {}) [p],obj)
const flatten = (obj) =>
Object .fromEntries (getPaths (obj) .map (p => [p.join('.'),path (p) (obj)]))
const input = {id: 45745049,seller: {first_name: "Sam",last_name: "Smith",email: "samsmith@smith.com",phone: {number: "1111-1111",verified: false}},order_items: [{item: {id: "29239765",title: "item1",colors: ["red","green","blue"]},quantity: 1,unit_price: 230},{item: {id: "238457363",title: "item2",colors: ["red"]},quantity: 2,unit_price: 110}],date_created: "2020-08-03T12: 17: 25.000-04: 00",date_last_updated: "2020-08-03T16: 51: 35.61Z"}
console .log (flatten (input))
.as-console-wrapper {min-height: 100% !important; top: 0}
区别在于数组索引之前有一个分隔符,我使用的是从零开始的数组,而不是从一个开始的数组。
我建议这是一种更好的输出格式。如果没有其他问题,它可能会让您重新补充原始格式。但是,如果要更改它,您可能应该简单地reduce
将数字元素与其前身组合的路径,例如:
const flatten = (obj) =>
Object .fromEntries (getPaths (obj) .map (p => [
p .reduce (
(a,k) => /^\d+$/ .test(k) ? [...a .slice (0,-1),a [a .length - 1] + (1 + (+k))] : [...a,k],[]
) .join ('.'),path2 (p) (obj)
]))
但是,如果外部对象可能是数组,则需要进行更改。
再说一次,由于没有很好的理由使用您要求的格式,我强烈建议您选择。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。