将对象对象数组转换为表格形式的新对象数组

Posted

技术标签:

【中文标题】将对象对象数组转换为表格形式的新对象数组【英文标题】:Transform Array of objects of objects into new array of objects in tabular form 【发布时间】:2021-12-28 22:54:30 【问题描述】:

鉴于示例数据,我需要转换给定的内容并以表格形式返回。这是样本数据。我怎样才能得到下面的输出?

var revisions = 
data:[
    // row 1
    
      cId: 
        value: "123456",
        oldValue: null
      ,
      revisionDate:
        value: "09/01/2021",
        oldValue: "09/21/2021"
      ,
      revisionType:
        value: "UPDATE",
        oldValue: "DELETE"
      ,
      revisionNote:
        value: "Some test note 0",
        oldValue: "Old revision note 0"
      ,
      financeNo:
        value: "FA1",
        oldValue: "FA2"
      
    ,
    // row 2
    
      dccId: 
        value: "123457",
        oldValue: null
      ,
      revisionDate:
        value: "05/01/2021",
        oldValue: "09/28/2021"
      ,
      revisionType:
        value: "NEW",
        oldValue: "UPDATE"
      ,
      revisionNote:
        value: "Some test note 1",
        oldValue: "Old revision note 1"
      ,
      financeNo:
        value: "FA4",
        oldValue: "FA5"
      ,
      maintNo:
        value: "MN001",
        oldValue: "MN002"
      ,
      isSpare:
        value: 0,
        oldValue: 1
      
    ,
    // row 3 ...
  ]

控制台输出应该是:

[
  cId: "123456", revisionDateNew: "09/01/2021", revisionDateOld:"09/21/2021", revisionTypeNew: "UPDATE",revisionTypeOld: "DELETE", revisionNoteNew: "Some test note 0", revisionNoteOld: "Old revision note 0", financeNoNew: "FA1", financeNoOld: "FA2", maintNoNew: "",      maintNoOld: "",      isSpareNew: "",  isSpareOld: "",
  cId: "123457", revisionDateNew: "05/01/2021", revisionDateOld:"09/28/2021", revisionTypeNew: "NEW",   revisionTypeOld: "UPDATE", revisionNoteNew: "Some test note 1", revisionNoteOld: "Old revision note 1", financeNoNew: "FA4", financeNoOld: "FA5", maintNoNew: "MN001", maintNoOld: "MN002", isSpareNew: "0", isSpareOld: "1", 
  ...
]

到目前为止,这就是我所做的,但我坚持如何不对属性进行硬编码,而且我还在努力找出将“新”和“旧”分配给当前属性所需的逻辑,然后给这些属性正确的值。

function loopData(revisions: any) 
  var newData = revisions.data.map(item => (
    cId: item.cId.value,
    revisionDateNew: item.revisionDate.value
  ))
  console.log(newData)

我认为我需要的是另一个循环,可能是一个 forEach,我在其中获取键,然后创建一个新数组来推送新字段。

【问题讨论】:

你能写一个函数来接受你旧表示的一个对象并创建一个对应的对象来解开value 字段吗?您可以将该函数传递给 revisions.data.map 函数以完成整个工作 好的,谢谢,我会努力的 澄清,您希望解决方案的类型安全程度如何?你用打字稿标记了这个问题,但现在尝试这样做我有一段时间让任何类型的类型都能正常工作 你想要像this 这样的东西,但是仅仅从数据声明中让它保留正确的类型是……很难 【参考方案1】:

我经常使用的通用函数objectMap 将对象中的每个字段映射到其他一些数据:

/**
 * similar to Array.map but for the fields of an object.
 * the callback takes the value as first argument and key as second.
 * does not support passing object as 3rd argument or thisArg.
 */
export function objectMap<T, V>(obj: T, fn: (val: T[keyof T], key: keyof T) => V) 
    // this is one of the cases where the as Record followed by a loop initializing all the keys
    // the whole reason this function exists is to have this typesafe outside :)
    // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
    const newObj =  as Record<keyof T, V>;
    for (const [key, val] of Object.entries(obj)) 
        newObj[key as keyof T] = fn(val, key as keyof T);
    
    return newObj;

有了这个你就可以用这个playground得到正确的数据结构了

const newData = revisions.data.map(v=>objectMap(v, x=>x?.value))

请注意,它不会完全保留类型,因为我们通常需要this feature 才能正确输入,您可能希望有一个接口来表示输出的类型,所以这可能不是问题给你。

【讨论】:

这真的很有帮助,谢谢。

以上是关于将对象对象数组转换为表格形式的新对象数组的主要内容,如果未能解决你的问题,请参考以下文章

摄取 JSON 对象数组并转换为表格数据

将带有值的新键添加到嵌套对象数组中

对象值的Javascript数组转换为多维数组

C#将对象转换为字节数组

对表格多数组的环回响应/将对象的嵌套数组展平为线性数组

在 Redshift 中解析一个 json 数组对象并转换为表格