Заменить имена полей некоторых объектов значениями другого объекта - PullRequest
0 голосов
/ 18 июня 2019

Предположим, у меня есть следующий массив JSON:

[
    [
         { "value": "first_name" },
         { "value": "last_name" },
         { "value": "age" }
    ],
    [
         { "value": "John" },
         { "value": "Johnson" },
         { "value": 27 }
    ],
    [
         { "value": "Martin" },
         { "value": "Martinson" },
         { "value": 18 }
    ]
]

Вы можете думать об этом JSON как о другом представлении:

| first_name | last_name | age |
|------------|-----------|-----|
| John       | Johnson   | 27  |
| Martin     | Martinson | 18  |

Первый элемент массива всегда представляет «столбцы» , в то время как остальные элементы являются строками.

Я бы хотел превратить вышеприведенный JSON во что-то более читаемое, то есть полностью избавиться от первого элемента, объединить все разделенные объекты и соответственно изменить имя поля:

[
    {
        "first_name": "John",
        "last_name": "Johnson",
        "age": 27
    },
    {
        "first_name": "Martin",
        "last_name": "Martinson",
        "age": 18
    }
]

В идеале я хотел бы добиться этого с помощью инструмента CLI, такого как jq - возможно ли это?

Ответы [ 2 ]

1 голос
/ 18 июня 2019

Вот еще один способ, которым вы можете построить желаемые результаты.

(.[0] | map({key:.value})) as $keys | [.[1:][] | [$keys,.] | transpose | map(add) | from_entries]

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

1 голос
/ 18 июня 2019

Следующий jq вызов работает для вашего образца ввода:

.[0] as $header | .[1:] | map( { ($header[0].value) : .[0].value, ($header[1].value) : .[1].value, ($header[2].value) : .[2].value } )

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

Вы можете попробовать здесь .

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


Редактировать (macicero @)

Это именно то, что я искал. Я улучшил ваш пример этой версией, которая не связана с числом столбцов:

[.[0][].value] as $cols | [.[1:][] | to_entries] | map(map({($cols[.key]): .value.value}) | add)
...