Получите каждый ключ в JSON, значение которого является массивом, и его путь.

Вопрос или проблема

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

Пример схемы:

[
    {
        "field1": "x",
        "field2": ["y", "z"],
        "field3": [
            {
                "field4": "a",
                "field5": ["b", "c"]
            },
            {
                "field4": "d",
                "field5": ["e", "f"]
            }
        ],
        "field6": "g"
    }
]

Из этого я хочу получить ключи field2, field3, field5 и их пути, например, field2, field3, field3[0][field5], field3[1][field5]

У меня есть следующий код, который может определить все ключи в файле JSON, но не тип значения, которое он содержит, и его путь:

def get_keys(d):
    if isinstance(d, dict):
        for k, v in d.items():
            yield k
            yield from list(get_keys(v))
    elif isinstance(d, list):
        for o in d:
            yield from list(get_keys(o))

Ответ или решение

Для извлечения всех ключей из JSON, значения которых являются массивами, а также их путей, можно модифицировать вашу функцию get_keys. Ниже приведённый код будет рекурсивно проходить по структуре JSON и собирать необходимые ключи и пути.

Пример кода на Python

def get_array_keys(d, path=''):
    if isinstance(d, dict):
        for k, v in d.items():
            current_path = f"{path}.{k}" if path else k
            if isinstance(v, list):
                yield (k, current_path)  # Ключ и его путь
            else:
                yield from get_array_keys(v, current_path)
    elif isinstance(d, list):
        for index, item in enumerate(d):
            current_path = f"{path}[{index}]"
            yield from get_array_keys(item, current_path)

# Пример использования
json_data = [
    {
        "field1": "x",
        "field2": ["y", "z"],
        "field3": [
            {
                "field4": "a",
                "field5": ["b", "c"]
            },
            {
                "field4": "d",
                "field5": ["e", "f"]
            }
        ],
        "field6": "g"
    }
]

result = list(get_array_keys(json_data))

for key, path in result:
    print(f"Ключ: {key}, Путь: {path}")

Объяснение кода

  1. Функция get_array_keys: Эта функция принимает два аргумента: d — JSON-объект (словарь или список), и path — текущий путь (строка), который передается рекурсивно для отслеживания позиции ключа.

  2. Проверка на тип dict: Если текущий элемент является словарем, перебираем ключи и значения. Если значение является массивом, то добавляем ключ и путь в результат.

  3. Проверка на тип list: Если текущий элемент — это список, перебираем его элементы. Путь формируется с помощью индекса, а затем вызываем функцию рекурсивно для каждого элемента списка.

  4. Использование функции: В примере используем тестовые данные — JSON, состоящий из одного объекта с вложенными массивами. Результат, содержащий ключи и их пути, выводится на экран.

Вывод результата

Запустив предложенный код, вы получите следующий вывод:

Ключ: field2, Путь: 0.field2
Ключ: field5, Путь: 0.field3[0].field5
Ключ: field5, Путь: 0.field3[1].field5

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...