JavaScript-正确提取深层对象属性并构造新对象

 收藏

假设从API返回以下对象数组:

const data = [
    { // first item
        meta: {
            stems: [
                "serpentine",
                "serpentinely"
            ]
        },
        hwi: {
            hw: "sep*pen*tine",
            prs: [
                {
                    mw: "ˈsər-pən-ˌtēn",
                    sound: {
                        audio: "serpen02"
                    }
                },
            ]
        },
        shortdef: [
            "of or resembling a serpent (as in form or movement)",
            "subtly wily or tempting",
            "winding or turning one way and another"
        ]
    },
    { // second item
        meta: {
            stems: [
                "moribund",
                "moribundities",
                "moribundity"
            ]
        },
        hwi: {
            hw: "mor*i*bund",
        },
        fl: "adjective"
    }
]

我想创建一个将生成对象新数组的函数。这个新数组中的对象将由刚刚重新排列的旧对象中的数据组成。这就是我期望新数组看起来的样子,例如:

[
  {
    word: 'serpentine',
    definitions: [
      'of or resembling a serpent (as in form or movement)',
      'subtly wily or tempting',
      'winding or turning one way and another'
    ]
  },
  {
    word: 'moribund',
    definitions: [
      'being in the state of dying : approaching death',
      'being in a state of inactivity or obsolescence'
    ],
    partOfSpeech: 'adjective'
  }
]

我使用以下功能执行此操作:

const buildNewData = arr => {
  const newData = []
  arr.forEach(item => {
    newData.push({
      ...item.meta.stems[0] && { word: item.meta.stems[0]},
      ...item.shortdef && { definitions: item.shortdef },
      ...item.fl && { partOfSpeech: item.fl },
      ...item.hwi.prs[0].mw && { pronunciation: item.hwi.prs[0].mw}
    })
  })
  return newData
}
buildNewData(data)

You may be curious as to why I use ...item.meta.stems[0] && { word: item.meta.stems[0]} in the creation of the new objects. This is to check if the property exists in the original object. If it doesn't exist, the expression will evaluate to false and therefore not be added to the new object. The first object in the original array does not have the fl property, so it evaluates to false when the new object is being constructed.

But this doesn't work when looking up a property that is an array. The code above fails with the error: TypeError: Cannot read property '0' of undefined. That's because the second item does not have a prs array under the hwi property, so the lookup fails.

由于我无法控制从API返回的数据,我该如何编写一个函数,该函数以我指定的格式成功创建新的对象数组,而不会引起错误?我已经有一个解决方案,可以在不存在特定属性的情况下不添加它们,但是如何考虑数组呢?

更笼统地说,我很好奇是否存在一种以编程方式从对象中提取数据的标准化方法,以防止发生此类错误。有一个更好的方法吗?

回复