Сглаживание JSON с дублированием объекта в свойстве массива для генерации CSV - PullRequest
1 голос
/ 08 июня 2019

Я ищу способ преобразовать данные JSON в плоский объект типа csv.В некотором смысле, я ищу "sqlirize" коллекцию mongodb.Я уже проверил некоторые библиотеки json flat в NPM, но ни одна из них не решает мою проблему.Я решил это по-своему, но хотел узнать, есть ли более эффективный способ.

У меня есть коллекция, которая представляет данные через 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"
}]

Несмотря на то, что я достиг ожидаемого результата, я все еще задаюсь вопросом, есть ли там другие библиотеки или есть более эффективный способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...