#json #jq
#json #jq
Вопрос:
Я пытаюсь подсчитать все элементы во вложенном JSON-документе с jq
помощью ?
Учитывая следующий JSON-документ
{"a": true, "b": [1, 2], "c": {"a": {"aa":1, "bb": 2}, "b": "blue"}}
Я хочу рассчитать результат 6
.
Для того, чтобы сделать это, я попробовал следующее:
echo '{"a": true, "b": [1, 2], "c": {"a": {"aa":1, "bb": 2}, "b": "blue"}}' | jq 'reduce (.. | if (type == "object" or type == "array") then length else 0 end) as $counts (1; . $counts)' # Actual output: 10 # Desired output: 6
Однако это также учитывает встречающиеся объекты и массивы и, следовательно, дает 10
противоположный желаемому результат: 6
Итак, как я могу считать только элементы/конечные узлы документа?
Заранее благодарю вас за помощь!
Правка: Каков был бы эффективный подход к подсчету пустых массивов и объектов?
Комментарии:
1. Пожалуйста, покажите пример желаемого результата. Какие шесть элементов в вашем примере ввода вы хотите выделить?
2. Я прояснил это, отредактировав вопрос. Я хочу подсчитать все конечные узлы и получить одно десятичное представление общего количества.
Ответ №1:
Вы можете использовать scalars
фильтр для поиска конечных узлов. Скаляры-это все «простые» значения JSON, т. Е. null
, true
, false
, числа и строки. В качестве альтернативы вы можете сравнить type
каждый элемент и использовать length
его для определения того, есть ли у объекта или массива дочерние элементы.
Я немного расширил ваши входные данные, чтобы выделить еще несколько угловых случаев:
Ввод:
{ "a": true, "b": [1, 2], "c": { "a": { "aa": 1, "bb": 2 }, "b": "blue" }, "d": [], "e": [[], []], "f": {} }
Это имеет 15 объектов JSON:
- 5 из них являются массивами или объектами с детьми.
- 4 из них являются пустыми массивами или объектами.
- 6 из них являются скалярами.
В зависимости от того, что вы пытаетесь сделать, вы можете рассматривать только скаляры как «конечные узлы», или вы можете рассматривать как скаляры, так и пустые массивы и объекты как конечные узлы.
Вот фильтр, который подсчитывает скаляры:
[..|scalars]|length
Выход:
6
И вот фильтр, который подсчитывает все сущности, у которых нет потомков. Он просто явно проверяет все скалярные типы (для значения JSON существует только шесть возможных типов), и если это не один из них, это должен быть массив или объект, где мы можем проверить, сколько у него дочерних length
элементов .
[ ..| select( (type|IN("boolean","number","string","null")) or length==0 ) ]| length
Выход:
10
Комментарии:
1. Отлично, спасибо вам! Каков был бы эффективный подход к подсчету пустых массивов и объектов?
2. Большое спасибо за добавление объяснения и решения для подсчета пустых объектов. Ваша статья с подробным описанием внутренней работы очень ценится.