【问题标题】:Javascript JSON transverse with hierarchical output具有分层输出的 Javascript JSON 横向
【发布时间】:2018-01-06 16:13:29
【问题描述】:

我正在尝试读取 JSON 模式,但似乎无法弄清楚如何将所有先前的对象等输出到层次结构中。

这是 JSON 响应方案

{
"Shopping": {
"Orders": {
  "OrderInfo": {
    "OrderNumber": "D0102864",
    "ContactID": "AS76372",
    "OrderDate": "01/01/2018",
    "Billing": {
      "BillingID": "B673472",
      "Name": "Fred Smith"
    },
    "Delivery": {
      "DeliveryID": "D769397",
      "Name": "Joe Blogg"
    },
    "Discount": {
      "DiscountValue": "10"
    },
    "OrderProduct": {
      "NumberofItems": "1",
      "Items": {
        "Item": {
          "ProductID": "P5763868",
          "ItemName": "Big Blue Box",
          "Price": "10",
        }
      }
    }
   }
  }
 }
}

添加多个项目数组[]

{
 "Shopping": {
"Orders": {
  "OrderInfo": {
    "OrderNumber": "D0102864",
    "ContactID": "AS76372",
    "OrderDate": "01/01/2018",
    "Billing": {
      "BillingID": "B673472",
      "Name": "Fred Smith"
    },
    "Delivery": {
      "DeliveryID": "D769397",
      "Name": "Joe Blogg"
    },
    "Discount": {
      "DiscountValue": "10"
    },
    "OrderProduct": {
      "NumberofItems": "2",
      "Items": {
        "Item": [
          {
          "ProductID": "P5763868",
          "ItemName": "Big Blue Box",
          "Price": "10",
          },
          {
          "ProductID": "P57638262",
          "ItemName": "Big Red Box",
          "Price": "20",
          }
        ]
      }
    }
   }
  }
 }
}

在下面的 javascript 函数中,我尝试生成输出结构 Object_nestedObject_Keyname,如下面的示例。请注意,JSON 是 Ajax 调用以及其他数据,但我只需要遍历购物对象。

 function js_traverse(o) {
 var type = typeof o 
 if (type == "object") {

    for (var key in o) {

        console.log("key: ", key)
        js_traverse(o[key])
    }
  } else {
    console.log("value: ",o)
  }
 }

 js_traverse(data['Shopping']); <- above scheme 

我试图在控制台日志中创建以下输出,类似于树形结构

 Orders
 Orders_OrdersInfo
 Orders_OrdersInfo_OrderNumber
 Orders_OrdersInfo_ContactID
 Orders_OrdersInfo_OrderDate
 Orders_OrdersInfo_Billing
 Orders_OrdersInfo_Billing_BillingID
 Orders_OrdersInfo_Billing_Name
 Orders_OrdersInfo_Delivery
 Orders_OrdersInfo_Delivery_DeliveryID
 Orders_OrdersInfo_Delivery_Name
 Orders_OrdersInfo_Discount
 Orders_OrdersInfo_Discount_DiscountValue
 Orders_OrdersInfo_OrderProduct
 Orders_OrdersInfo_OrderProduct_NumberofItems
 Orders_OrdersInfo_OrderProduct_Items
 Orders_OrdersInfo_OrderProduct_Items_Item
 Orders_OrdersInfo_OrderProduct_Items_Item_ProductID_1 <-- increment number at end if multiple item
 Orders_OrdersInfo_OrderProduct_Items_Item_ItemName_1 <-- increment at end if multiple item
 Orders_OrdersInfo_OrderProduct_Items_Item_Price_1 <-- increment at end if multiple item

【问题讨论】:

  • 为什么需要以1开头的数字而不是索引?
  • 谢谢,没关系,我可以用索引代替
  • 里面只有一个数组吗?为什么最后是数字?

标签: javascript json tree


【解决方案1】:

您可以通过检查值和类型来使用递归方法,然后获取 kthe 键或显示对象的路径。

function getKeys(object) {
    function iter(o, p) {
        if (o && typeof o === 'object') {
            Object.keys(o).forEach(k => iter(o[k], p.concat(k)));
        } else {
            console.log(p.join('_'));
        }
    }
    iter(object, []);
}

var object = { Shopping: { Orders: { OrderInfo: { OrderNumber: "D0102864", ContactID: "AS76372", OrderDate: "01/01/2018", Billing: { BillingID: "B673472", Name: "Fred Smith" }, Delivery: { DeliveryID: "D769397", Name: "Joe Blogg" }, Discount: { DiscountValue: "10" }, OrderProduct: { NumberofItems: "2", Items: { Item: [{ ProductID: "P5763868", ItemName: "Big Blue Box", Price: "10" }, { ProductID: "P57638262", ItemName: "Big Red Box", Price: "20" }] } } } } } };

getKeys(object);
.as-console-wrapper { max-height: 100% !important; top: 0; }

用于从给定数组中生成带有键和值的数组/对象的附加功能。这适用于检查给定键是否为数字。

function setValue(object, path, value) {
    var last = path.pop();

    path.reduce((o, k, i, kk) => o[k] = o[k] || (isFinite(i + 1 in kk ? kk[i + 1] : last) ? [] : {}), object)[last] = value;
}

function getValues(object) {
    function iter(o, p) {
        if (o && typeof o === 'object') {
            Object.keys(o).forEach(k => iter(o[k], p.concat(k)));
        } else {
            result.push([p, o]);
        }
    }

    var result = [];
    iter(object, []);
    return result;
}

var object = { Shopping: { Orders: { OrderInfo: { OrderNumber: "D0102864", ContactID: "AS76372", OrderDate: "01/01/2018", Billing: { BillingID: "B673472", Name: "Fred Smith" }, Delivery: { DeliveryID: "D769397", Name: "Joe Blogg" }, Discount: { DiscountValue: "10" }, OrderProduct: { NumberofItems: "2", Items: { Item: [{ ProductID: "P5763868", ItemName: "Big Blue Box", Price: "10" }, { ProductID: "P57638262", ItemName: "Big Red Box", Price: "20" }] } } } } } },
    values = getValues(object),
    objectFromValues = {};

values.forEach(([keys, value]) => setValue(objectFromValues, keys, value));

console.log(objectFromValues);
console.log(values)
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 哇,真快!谢谢妮娜。打算在我的设置中尝试一下
  • 是否可以将上述函数输出(如“Shopping_Orders_OrderInfo_OrderNumber”等)重建回 JSON 模式?假设“Shopping_Orders_OrderInfo_OrderNumber”等都是字段 ID/名称,我需要将它们的键和值构造回 JSON 模式。
  • 谢谢尼娜,太好了。但是,如果数据值现在取自 字段(而不是 JSON 对象/数组),然后重新编译成 JSON 对象,这怎么可能?就像上面的代码一样,但是从字段中收集数据以生成 JSON 模式。
  • 然后将'_'分割的名称作为路径,值作为值。还是我错过了什么?
  • 所以为了清楚起见,这个问题的第一部分(在顶部)是从 JSON 创建字段 (Shopping_Orders_OrderInfo_OrderNumber),然后第二部分是获取字段的值并重建JSON 以及对象键和值,如上面的架构(第一部分)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 2013-09-06
相关资源
最近更新 更多