Рекурсивно фильтровать вложенные данные json, используя javascript или rxjs - PullRequest
1 голос
/ 15 апреля 2020

Я ищу элегантное решение для фильтрации вложенной json структуры данных, чтобы можно было применить функциональность фильтра.

предварительные условия:

  • Глубина неизвестна (требуется рекурсивное решение)
  • , если значение не совпадает и у него есть потомки, тогда как все потомки должны быть привязаны к родителю и должны быть рекурсивными.
  • Фильтр должен работать больше чем один Под чем я подразумеваю, если выбрать фильтр По Y и Z, тогда результаты Y и Z должны быть показаны в древовидной структуре. Но приведенный ниже пример для фильтра по kind свойству и значению для фильтра: Y.

Спасибо !!

например

   var dataToFilter = {
        "children": [{
            "tagPath": "/../../tagPath-1",
            "children": [{
                "tagPath": "/../../tagPath-1-1",
                "children": [{
                        "tagPath": "/../../tagPath-1-2",
                        "kind": "Y",
                        "children": [{
                                "tagPath": "/../../tagPath-1-3.1",
                                "kind": "X",
                                "children": []
                            },
                            {
                                "tagPath": "/../../tagPath-1.3.2",
                                "kind": "X",
                                "children": [{
                                    "tagPath": "/../../tagPath-1.3",
                                    "kind": "Y",
                                    "children": []
                                }]
                            }
                        ]
                    },
                    {
                        "kind": "Y",
                        "children": []
                    }
                ],
                "kind": "X",
            }],
            "kind": "Y",
        }]

Требуемый вывод для свойства kind, когда значение, например, Y:

var desiredOutput = {
        "children": [{
            "tagPath": "/../../tagPath-1",
            "children": [{
                    "tagPath": "/../../tagPath-1-2",
                    "kind": "Y",
                    "children": [{
                        "tagPath": "/../../tagPath-1.3",
                        "kind": "Y",
                        "children": []
                    }]
                },
                {
                    "kind": "Y",
                    "children": []
                }
            ],
            "kind": "Y",
        }]
    ```

1 Ответ

1 голос
/ 17 апреля 2020

Вы можете использовать следующую функцию:

const restructure = (nodes, filter) => nodes.reduce(
    (acc, node) => {
        const children = restructure(node.children, filter);

        return acc.concat(
            filter(node)
                ? {...node, children}
                : children
        );
    },
    []
);

, которая принимает filter в качестве функции. Это позволяет вам решить, как фильтровать, например:

const yOnly = restructure(dataToFilter, node => 'Y' === node.kind);

Или:

const yAndX = restructure(dataToFilter, node => ['Y', 'X'].includes(node.kind));

Единственное отличие вашего кода выше в том, что dataToFilter уже должен быть массивом узлов (см. полный фрагмент кода ниже).

const restructure = (nodes, filter) => nodes.reduce(
    (acc, node) => {
        const children = restructure(node.children, filter);

        return acc.concat(
            filter(node)
                ? {...node, children}
                : children
        );
    },
    []
);

const dataToFilter = [{
    'tagPath':  '/../../tagPath-1',
    'children': [{
        'tagPath':  '/../../tagPath-1-1',
        'children': [{
            'tagPath':  '/../../tagPath-1-2',
            'kind':     'Y',
            'children': [{
                'tagPath':  '/../../tagPath-1-3.1',
                'kind':     'X',
                'children': []
            }, {
                'tagPath':  '/../../tagPath-1.3.2',
                'kind':     'X',
                'children': [{
                    'tagPath':  '/../../tagPath-1.3',
                    'kind':     'Y',
                    'children': []
                }]
            }]
        }, {
            'kind':     'Y',
            'children': []
        }],
        'kind':     'X',
    }],
    'kind':     'Y',
}];

const yOnly = restructure(dataToFilter, node => 'Y' === node.kind);
const xOnly = restructure(dataToFilter, node => 'X' === node.kind);
const yAndX = restructure(dataToFilter, node => ['Y', 'X'].includes(node.kind));

console.log(yOnly);
console.log(xOnly);
console.log(yAndX);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...