标准化 javascript 个对象数组中的键

Standardize keys in array of javascript objects

我正在处理来自 Web 服务的 JSON 响应,如果值为 null,该响应会删除键。这种做法很合理,但我将响应用作报告组件的数据源,该组件使用对象数组中的第一个值作为其余对象中所有可用字段的真实来源。

报告组件正在调用我编写和控制的无服务器 javascript 端点。所以我可以处理结果并可能在发送响应之前标准化此 js 代码中的 JSON 对象键。

更棘手的是,数据的形状 and/or 字段是可变的。它是用户提供的 GraphQL 查询的结果。

所以这样的查询:

    query GetCustomersByState($state: String!) {
      Customer(where: { State: { _eq: $state } }) {
        CustomerID
        CustomerName
        Address1
        Address2
        City
        State
        Zip
      }
    }

可能导致:

[
    {
      CustomerID: 'TENASPH',
      CustomerName: 'Tennessee Asphalt',
      Address1: '123 main st',
      City: 'Somewhere',
      State: 'TN'
    },
    {
      CustomerID: '10002',
      CustomerName: 'A&N Drywall',
      Address1: '123 Drywall Ln',
      Address2: 'Suite 2',
      City: 'Somewhere',
      State: 'TN',
      Zip: '12345'
    },
    {
      CustomerID: 'JONES',
      CustomerName: 'Jones Bros Construction',
      City: 'Somewhere',
      State: 'TN',
      Zip: '37917'
    },
]

如何标准化对象数组中的键?

(如果有帮助,数据源是一个 Hasura GraphQL 服务器实例。我查看了 Hasura 界面,似乎找不到任何会在响应中包含空白的设置。如果确实存在,那就太好了.)

列出所有字段的查询本身应该是所有当前字段的真实来源,而不是第一个返回的对象。 如果无论如何都没有返回对象怎么办?

GraphQL 实际上支持 introspection,这应该允许您查询对象的字段。我不确定这是否允许您查询查询本身的字段,但同样:查询应该写成 manually/once,因此您应该已经知道存在哪些字段。

您可以通过查找所有唯一密钥来提前设置密钥,然后在 map() 中验证它们

let response = [{
    CustomerID: 'TENASPH',
    CustomerName: 'Tennessee Asphalt',
    Address1: '123 main st',
    City: 'Somewhere',
    State: 'TN'
  },
  {
    CustomerID: '10002',
    CustomerName: 'A&N Drywall',
    Address1: '123 Drywall Ln',
    Address2: 'Suite 2',
    City: 'Somewhere',
    State: 'TN',
    Zip: '12345'
  },
  {
    CustomerID: 'JONES',
    CustomerName: 'Jones Bros Construction',
    City: 'Somewhere',
    State: 'TN',
    Zip: '37917'
  },
]

let keys = [...new Set(response.flatMap(Object.keys))];
//console.log(keys)
let standardized = response.map(e => {
  keys.forEach(k => {
    if (!e[k]) e[k] = '';
  })
  return e
})
console.log(standardized)