JSON массив Pad с JQ для получения прямоугольного результата - PullRequest
0 голосов
/ 01 марта 2019

У меня есть json, который выглядит как this (jq play в ссылке), и я хочу в конце создать csv, выглядящий так (воспроизводимый образец внизу).

"SO302993",items1,item2,item3.1,item3.2,item3.3, item3.4,...
"SO302994",items1,item2,item3.1,item3.2,       ,        ,...
"SO302995",items1,item2,item3.1,item3.2,item3.3,        ,...

элементы item3 находятся в массиве, и мое текущее решение:

.[] | [.number, .item1, item2, item3[]?]

дает мне следующее:

"SO302993",items1,item2,item3.1,item3.2,item3.3, item3.4,...
"SO302994",items1,item2,item3.1,item3.2,...
"SO302995",items1,item2,item3.1,item3.2,item3.3,...

, что создаст неравное количество столбцовв CSV.

Я пытался добавить .item3[:]? в стиле Python, но это не сработало.

Любая помощь будет высоко ценится!И если я не был ясен, попросите уточнить!Мои данные об фрагменте и игрушке находятся по ссылке выше.

{
  "items": [
    {
      "name": "Mr Simon Mackin",
      "country_of_residence": "Scotland",
      "natures_of_control": [
        "voting-rights-25-to-50-percent-limited-liability-partnership",
        "significant-influence-or-control-limited-liability-partnership"
      ],
      "premises": "4"
    }
  ]
}
{
  "items": [
    {
      "name": "Mrs Simonne Mackinni",
      "country_of_residence": "France",
      "natures_of_control": [
        "significant-influence-or-control-limited-liability-partnership"
      ],
      "premises": "4"
    }
  ]
}

с этим запросом:

.items[] | [.name, .country_of_residence, .natures_of_control[]?, .premises] | @csv

Я получаю эти результаты

"Mr Simon Mackin","Scotland","voting-rights","significant-influence","4"
"Mrs Simonne Mackinni","France","significant-influence","4"

Но я хотел бы получить это (вторая строка имеет дополнительную запятую после«значительное влияние».

"Mr Simon Mackin","Scotland","voting-rights","significant-influence","4"
"Mrs Simonne Mackinni","France","significant-influence",,"4"

1 Ответ

0 голосов
/ 01 марта 2019

Поскольку вы хотите получить прямоугольный результат, вам придется "дополнить" массив "natures_of_control".Основываясь на примере входных данных, вам потребуется «отбросить» входные данные, чтобы получить глобальный максимум.

Для заполнения массива вы можете использовать вспомогательную функцию:

# emit a stream of exactly $n items
def pad($n): range(0;$n) as $i | .[$i];

Решение проблемы, опубликованное в jqplay, выглядит следующим образом:

([.[] | .items[] | .natures_of_control | length] | max) as $mx
| .[]
| (.active_count) as $active_count
| (.ceased_count) as $ceased_count
| (.links.self | split("/")[2]) as $companyCode
| .items[]
| [$companyCode, $active_count, $ceased_count, .name, .country_of_residence, .nationality, .notified_on, (.natures_of_control | pad($mx))]
| @csv

Вызов

Соответствующий вызов будет выглядеть следующим образом:

jq -sr -f program.jq input.json

Обработка пропущенных данных

Чтобы игнорировать объекты, у которых нет «предметов», вы можете настроить вышеперечисленное, например, следующим образом:

([.[] | .items[]? | .natures_of_control | length] | max) as $mx
 | .[]
 | select(.items)
 | (.active_count) as $active_count
 | (.ceased_count) as $ceased_count
 | (.links.self | split("/")[2]) as $companyCode
 | .items[]
 | [$companyCode, $active_count, $ceased_count, .name, .country_of_residence, .nationality, .notified_on, (.natures_of_control | pad($mx))]
 | @csv
...