繁体   English   中英

(递归)如何从具有嵌套对象和数组的对象中获取所有键/值对

[英](Recursion) How to get all key/value pairs from an Object with nested objects and arrays

我有一个看起来像这样的对象:

        {
            "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", "red"], 
   ...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];
    
}

注意:我不想要空键或空键。

如果有人可以帮助我,我将不胜感激。 不管怎么说,多谢拉!

这与您正在寻找的内容非常相似。 这是我经常使用的技术。

 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)
  ]))

但是如果外部对象可能是一个数组,这将需要更改。

同样,虽然没有很好的理由使用您所要求的格式,但我强烈推荐我的替代方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM