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

Transform Array of objects of objects into new array of objects in tabular form

鉴于示例数据,我需要将给定的内容和 return 转换为表格形式。这是示例数据。我怎样才能得到下面的输出?

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

到目前为止,这就是我所做的,但我仍然坚持如何不对属性进行硬编码,我也在努力找出将 'New' 和 'Old' 分配给当前所需的逻辑属性,然后赋予它们正确的值。

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

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

一个我经常使用的通用函数 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 来正确键入它,您可能需要一个接口来表示输出的类型,所以这可能是对你来说不是问题。