плоский CSV для вложенного дерева JSON для D3.js - PullRequest
0 голосов
/ 11 мая 2018

У меня есть много данных в CSV, которые мне нужно преобразовать во вложенный JSON для использования в дереве D3.js.

Вот пример данных CSV:

Domain,Subject,Section,Topic
Networking,Networking Communications,Data Transmission,Data - Overview
Networking,Networking Communications,Data Transmission,Email
Networking,Networking Communications,Data Transmission,Datagram
Networking,Networking Communications,Networking Models,OSI Model
Networking,Networking Communications,Networking Models,TCP/IP Mode

Вот как должен выглядеть JSON:

{
    "name":"Networking",
    "groups":["CS Analyst", "Cyber Crime"],
    "children":[
        {
            "name":"Networking Communications",
            "groups":["CS Analyst", "Cyber Crime"],
            "children":[
                {
                    "name":"Data Transmission",
                    "groups":["CS Analyst", "Cyber Crime"],
                    "children":[
                        {
                            "name":"Data - Overview",
                            "groups":["CS Analyst", "Cyber Crime"],
                        },
                        {
                            "name":"Email",
                            "groups":["CS Analyst", "Cyber Crime"],
                        },
                        {
                            "name":"Datagram",
                            "groups":[],
                        }
                    ]
                },
                {
                    "name":"Networking Models",
                    "groups":["CS Analyst"],
                    "children":[
                        {
                            "name":"OSI Model",
                            "groups":["CS Analyst"],
                        },
                        {
                            "name":"TCP/IP Model",
                            "groups":["CS Analyst"],
                        }
                    ]
                },

Ответы [ 2 ]

0 голосов
/ 12 мая 2018
var data = [
  "Networking, Networking Communications, Data Transmission, Data-Overview",
  "Networking, Networking Communications, Data Transmission, Email",
  "Networking, Networking Communications, Data Transmission, Something",
  "Networking,  Networking Communications,   Collection Management,   Logs",
  "Networking,  Networking Communications,   Collection Management,   Backups",
  "Networking,  Networking Communications,   Collection Management,   Configuration files",
  "Networking,  Network Architecture,    Architecture Concepts,   Types",
  "Networking,  Network Architecture,    Architecture Concepts,  Design",
  "Networking,  Network Architecture,    Network Topologies,  Comm Medias",
  "Networking,  Network Architecture,    Network Topologies,  Implementations",
  "Networking,  Network Architecture,    Intranet Extranet,  Zoning"
]

var arrayToTree = (finalArray, currentArray) => {
  var node

  currentArray.forEach((name, index) => {
    const children = index === 0 ? finalArray : node['children']
    let newNode = children.find(child => child.name === name)

    if (!newNode) {
      newNode = {
        name,
        ...(
          index < currentArray.length - 1
          ? { children: [] }
          : {}
        )
      }

      children.push(newNode)
    }

    node = newNode
  })

  return finalArray
}

var finalResult = data.map(row => row.split(/,\s+/)).reduce(arrayToTree, [])
0 голосов
/ 11 мая 2018

Вот подход jq , который поддерживает неограниченное вложение с использованием рекурсии.Поскольку неясно, как именно нужно вычислять значение groups, следующая программа (program.jq) использует фиксированное значение.Если вы можете указать алгоритм определения значения, его легко включить в программу.

Ключом к пониманию program.jq является понимание group_by(f), которое группирует элементы входного массива в массивмассивов.

program.jq

def gather($supplement):
  group_by(.[0])
  | map( {name: .[0][0]} 
         + $supplement +
         {children: (if (.[0]|length) > 2
                     then (map(.[1:]) | gather($supplement))
                     else map({name:.[1]} + $supplement)
                     end) } )
  ;

split("\n") | map(split(","))
| .[1:] # skip the headers
| map(select(length>0))
| gather({"groups":["CS Analyst", "Cyber Crime"]})
| .[]

Вызов:

 jq -Rs -f program.jq nested.csv

Вывод:

  {
    "name": "Networking",
    "groups": [
      "CS Analyst",
      "Cyber Crime"
    ],
    "children": [
      {
        "name": "Networking Communications",
        "groups": [
          "CS Analyst",
          "Cyber Crime"
        ],
        "children": [
          {
            "name": "Data Transmission",
            "groups": [
              "CS Analyst",
              "Cyber Crime"
            ],
            "children": [
              {
                "name": "Data - Overview",
                "groups": [
                  "CS Analyst",
                  "Cyber Crime"
                ]
              },
              {
                "name": "Email",
                "groups": [
                  "CS Analyst",
                  "Cyber Crime"
                ]
              },
              {
                "name": "Datagram",
                "groups": [
                  "CS Analyst",
                  "Cyber Crime"
                ]
              }
            ]
          },
          {
            "name": "Networking Models",
            "groups": [
              "CS Analyst",
              "Cyber Crime"
            ],
            "children": [
              {
                "name": "OSI Model",
                "groups": [
                  "CS Analyst",
                  "Cyber Crime"
                ]
              },
              {
                "name": "TCP/IP Mode",
                "groups": [
                  "CS Analyst",
                  "Cyber Crime"
                ]
              }
            ]
          }
        ]
      }
    ]
  }
...