通过数组属性上的对象重复进行JSON扁平化以生成CSV

时间:2019-06-07 23:02:51

标签: javascript node.js json csv flat

我正在寻找一种将JSON数据转换为平面“类似于csv”数据对象的方法。以某种方式,我希望“ sqlirize”一个mongodb集合。我已经在NPM中检查了一些json平面库,但是没有一个可以解决我的问题。我已经以自己的方式解决了该问题,但想知道是否有更有效的方法。

我有一个集合,该集合以以下方式通过API呈现数据:

[{
    "data": {
        "name": "John",
        "age": 23,
        "friends": [{
            "name": "Arya",
            "age": 18,
            "gender": "female"
        }, {
            "name": "Sansa",
            "age": 20,
            "gender": "female"
        }, {
            "name": "Bran",
            "age": 17,
            "gender": "male"
        }]
    }
}, {
    "data": {
        "name": "Daenerys",
        "age": 24,
        "friends": [{
            "name": "Grey Worm",
            "age": 20,
            "gender": "male"
        }, {
            "name": "Missandei",
            "age": 17,
            "gender": "female"
        }]
    }
}]

这是我创建的用于重新整理安全展开的json的函数(例如,除数组外,所有内容均已整理)

const { cloneDeep } = require('lodash')
const flatten = require('flat')

const reflatten = (items) => {
  const reflatted = []

  items.forEach(item => {
    let array = false

    for (const key of Object.keys(item)) {
      if (Array.isArray(item[key])) {
        array = true

        const children = Array(item[key].length).fill().map(() => cloneDeep(item))

        for (let i = 0; i < children.length; i++) {
          const keys = Object.keys(children[i][key][i])

          keys.forEach(k => {
            children[i][`${key}.${k}`] = children[i][key][i][k]
          })
          delete children[i][key]
          reflatted.push(children[i])
        }
        break
      }
    }
    if (!array) {
      reflatted.push(item)
    }
  })

  return reflatted.length === items.length
    ? reflatted
    : reflatten(reflatted)
}

const rows = []

for (const item of items) {
  const flat = [flatten(item)]

  rows.push(...reflatten(flat)]
}

console.log(rows)

预期(和当前)输出如下:

[{
    "data.name": "John",
    "data.age": 23,
    "data.friends.name": "Arya",
    "data.friends.age": 18,
    "data.friends.gender": "female"
}, {
    "data.name": "John",
    "data.age": 23,
    "data.friends.name": "Sansa",
    "data.friends.age": 20,
    "data.friends.gender": "female"
}, {
    "data.name": "John",
    "data.age": 23,
    "data.friends.name": "Bran",
    "data.friends.age": 17,
    "data.friends.gender": "male"
}, {
    "data.name": "Daenerys",
    "data.age": 24,
    "data.friends.name": "Grey Worm",
    "data.friends.age": 20,
    "data.friends.gender": "male"
}, {
    "data.name": "Daenerys",
    "data.age": 24,
    "data.friends.name": "Missandei",
    "data.friends.age": 17,
    "data.friends.gender": "female"
}]

虽然我达到了预期的输出,但我一直在想是否还有其他库,或者是否有更有效的方法来实现。

0 个答案:

没有答案