使用lodash展平对象 [英] Flatten an object using lodash

查看:96
本文介绍了使用lodash展平对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我下面有 此嵌套对象

我需要使用包含keys的该对象创建一个数组.如果keys是对象,则应使用.dot语法.如果它是一个数组,那么应该给我key.0.keyName.有可能这样做吗?

I need to create an array using this object containing keys. And if keys are object then it should use .dot syntax. and if it is an array then it should give me key.0.keyName. Is it possible to do so?

输出

[
  "AllowIPNPayment",
  "AllowOnlinePayment",
  "MetaData.CreateTime",
  "MetaData.LastUpdatedTime",
  "CustomField.0.DefinitionId",
  "CustomField.0.Name",
  "CustomField.0.Type",
  ...
]

我尝试过的只是丑陋的,确实给了我预期的结果.如果可能的话,可以使用更简洁的方式.

What I have tried is just ugly and does give me expected result. If it is possible with more concise way.

const invoiceObject = { "AllowIPNPayment": false, "AllowOnlinePayment": false, "AllowOnlineCreditCardPayment": false, "AllowOnlineACHPayment": false, "domain": "QBO", "sparse": false, "Id": "16", "SyncToken": "1", "MetaData": { "CreateTime": "2020-03-25T15:10:40-07:00", "LastUpdatedTime": "2020-03-26T11:06:49-07:00" }, "CustomField": [{ "DefinitionId": "1", "Name": "Crew #", "Type": "StringType" }], "DocNumber": "1007", "TxnDate": "2020-03-03", "CurrencyRef": { "value": "USD", "name": "United States Dollar" }, "LinkedTxn": [{ "TxnId": "32", "TxnType": "Payment" }], "Line": [{ "Id": "1", "LineNum": 1, "Description": "Custom Design", "Amount": 750, "DetailType": "SalesItemLineDetail", "SalesItemLineDetail": { "ItemRef": { "value": "4", "name": "Design" }, "UnitPrice": 75, "Qty": 10, "TaxCodeRef": { "value": "NON" } } }, { "Amount": 750, "DetailType": "SubTotalLineDetail", "SubTotalLineDetail": {} } ], "TxnTaxDetail": { "TotalTax": 0 }, "CustomerRef": { "value": "13", "name": "uiool" }, "CustomerMemo": { "value": "Thank you for your business and have a great day!" }, "SalesTermRef": { "value": "3" }, "DueDate": "2020-04-02", "TotalAmt": 750, "ApplyTaxAfterDiscount": false, "PrintStatus": "NeedToPrint", "EmailStatus": "NotSet", "BillEmail": { "Address": "uiikoool" }, "Balance": 450 }

let object = {}
for (let k in invoiceObject) {
  if (typeof invoiceObject[k] === "object") {
    object[k] = {};
    for (let l in invoiceObject[k]) {
      object[k][l] = "";
    }
  } else if (typeof invoiceObject[k] === "array") {
    object[k] = [];
    for (let l in invoiceObject[k][0]) {
      object[k][l] = "";
    }
  } else {
    object[k] = "";
  }
}
console.log(object)

推荐答案

您可以创建一个递归函数(getSchema),该函数检查值(val)是否为对象(包括数组),并使用_.flatMap(),并收集键,直到它达到不是对象的值为止.然后它将收集的键连接起来并返回字符串.

You can create a recursive function (getSchema) that checks if a value (val) is an object (arrays included), iterate it with _.flatMap(), and collects the keys until it hits a value which is not an object. It then joins the collected keys and returns the string.

const getSchema = (val, keys = []) =>
  _.isObject(val) ? // if it's an object or array
    _.flatMap(val, (v, k) => getSchema(v, [...keys, k])) // iterate it and call fn with the value and the collected keys
    :
    keys.join('.') // return the joined keys

const invoiceObject = { "AllowIPNPayment": false, "AllowOnlinePayment": false, "AllowOnlineCreditCardPayment": false, "AllowOnlineACHPayment": false, "domain": "QBO", "sparse": false, "Id": "16", "SyncToken": "1", "MetaData": { "CreateTime": "2020-03-25T15:10:40-07:00", "LastUpdatedTime": "2020-03-26T11:06:49-07:00" }, "CustomField": [{ "DefinitionId": "1", "Name": "Crew #", "Type": "StringType" }], "DocNumber": "1007", "TxnDate": "2020-03-03", "CurrencyRef": { "value": "USD", "name": "United States Dollar" }, "LinkedTxn": [{ "TxnId": "32", "TxnType": "Payment" }], "Line": [{ "Id": "1", "LineNum": 1, "Description": "Custom Design", "Amount": 750, "DetailType": "SalesItemLineDetail", "SalesItemLineDetail": { "ItemRef": { "value": "4", "name": "Design" }, "UnitPrice": 75, "Qty": 10, "TaxCodeRef": { "value": "NON" } } }, { "Amount": 750, "DetailType": "SubTotalLineDetail", "SubTotalLineDetail": {} } ], "TxnTaxDetail": { "TotalTax": 0 }, "CustomerRef": { "value": "13", "name": "uiool" }, "CustomerMemo": { "value": "Thank you for your business and have a great day!" }, "SalesTermRef": { "value": "3" }, "DueDate": "2020-04-02", "TotalAmt": 750, "ApplyTaxAfterDiscount": false, "PrintStatus": "NeedToPrint", "EmailStatus": "NotSet", "BillEmail": { "Address": "uiikoool" }, "Balance": 450 }

const result = getSchema(invoiceObject)

console.log(result)

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

在没有破折号的情况下,主要更改是使用Object.entries()获取[键,值]对的数组,因为Array.flatMap()无法迭代对象:

Without lodash, the main change is to use Object.entries() to get an array of [key, value] pairs, since Array.flatMap() can't iterate objects:

const getSchema = (val, keys = []) =>
  typeof val === 'object' && val !== null ? // if it's an object or array
    Object.entries(val) // get [key, value] pairs of object/array
      .flatMap(([k, v]) => getSchema(v, [...keys, k])) // iterate it and call fn with the value and the collected keys 
    :
    keys.join('.') // return the joined keys

const invoiceObject = { "AllowIPNPayment": false, "AllowOnlinePayment": false, "AllowOnlineCreditCardPayment": false, "AllowOnlineACHPayment": false, "domain": "QBO", "sparse": false, "Id": "16", "SyncToken": "1", "MetaData": { "CreateTime": "2020-03-25T15:10:40-07:00", "LastUpdatedTime": "2020-03-26T11:06:49-07:00" }, "CustomField": [{ "DefinitionId": "1", "Name": "Crew #", "Type": "StringType" }], "DocNumber": "1007", "TxnDate": "2020-03-03", "CurrencyRef": { "value": "USD", "name": "United States Dollar" }, "LinkedTxn": [{ "TxnId": "32", "TxnType": "Payment" }], "Line": [{ "Id": "1", "LineNum": 1, "Description": "Custom Design", "Amount": 750, "DetailType": "SalesItemLineDetail", "SalesItemLineDetail": { "ItemRef": { "value": "4", "name": "Design" }, "UnitPrice": 75, "Qty": 10, "TaxCodeRef": { "value": "NON" } } }, { "Amount": 750, "DetailType": "SubTotalLineDetail", "SubTotalLineDetail": {} } ], "TxnTaxDetail": { "TotalTax": 0 }, "CustomerRef": { "value": "13", "name": "uiool" }, "CustomerMemo": { "value": "Thank you for your business and have a great day!" }, "SalesTermRef": { "value": "3" }, "DueDate": "2020-04-02", "TotalAmt": 750, "ApplyTaxAfterDiscount": false, "PrintStatus": "NeedToPrint", "EmailStatus": "NotSet", "BillEmail": { "Address": "uiikoool" }, "Balance": 450 }

const result = getSchema(invoiceObject)

console.log(result)

这篇关于使用lodash展平对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆