Фильтр javascript массив с вложенным массивом childern и возвращаемым родителем - PullRequest
0 голосов
/ 27 января 2020

Заранее спасибо. Я имею массив ниже и пытаюсь работать с фильтром массива в javascript.

[{ID: 16,ItemName: "SomeData 1", children : []},
{ID: 19,ItemName: "SomeData 2",  children : [{ID: 51,ItemName: "SomeData 3"},{ID: 41,ItemName: "SomeData 4"},{ID: 16,ItemName: "SomeData 5"}]}
{ID: 14, ItemName: "SomeData 4", children : [{ID: 21,ItemName: "SomeData 9"}]}]

Если я ищу SomeData 4 , то при использовании фильтра это должно вернуть мне что-то вроде

[{ID: 19,ItemName: "SomeData 2",  children : [{ID: 41,ItemName: "**SomeData 4**"}]}
{ID: 14, ItemName: "**SomeData 4**", children : [{ID: 21,ItemName: "SomeData 9"}]}]

Q1) Что, если ключевые слова для поиска совпадают с любым объектом в потомке, они должны возвращать включающее родительское содержимое. Даже если он совпадает с parent, тогда он должен вернуть parent и child. (Я сделал с этой частью)

const filteredContent = ItemsList.filter(item => {
   return item.ItemName.indexOf(value) !== -1;
});

Может кто-нибудь может предложить лучший способ извинить Q1

Ответы [ 3 ]

2 голосов
/ 27 января 2020

Модифицированное решение для n-детей в объекте и их потомков для n итераций. Используйте ту же функцию, но рекурсивно. Следующая функция работает.

var data = [{
    ID: 16,ItemName: "SomeData 1",
    children: [],children: [{ID: 73,ItemName: "SomeData 3"}, 
                            {ID: 57,ItemName: "SomeData 4"}, 
                            {ID: 59,ItemName: "SomeData 5"}]
  },
  {
    ID: 19,ItemName: "SomeData 2",
    children: [{ID: 51,ItemName: "SomeData 3"}, 
               {ID: 41,ItemName: "SomeData 4"}, 
               {ID: 16,ItemName: "SomeData 5"}]
  },
  {
    ID: 14,ItemName: "SomeData 4",
    children: [{ID: 21,ItemName: "SomeData 9"}]
  }
]

const filteredContent = (ItemsList, value) => {
  return ItemsList.filter(item => {
    let hasValue = item.ItemName.indexOf(value) !== -1
    if (!hasValue) {
      for (let key in item) {
        if (key === 'children') {
          item.children = filteredContent(item.children, value);
          hasValue = item.children && item.children.length > 0;
        }
      }

    }
    return hasValue
  });
}

console.log(filteredContent(data, 'SomeData 4'));

Надеюсь, что это решение, которое вы ожидаете.

1 голос
/ 27 января 2020

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

Если children содержит результат, создайте новый объект с обновленным свойством дочерних элементов.

const
    find = (r, o) => {
        if (o.ItemName === search) r.push(o);
        else {
            var children = (o.children || []).reduce(find, []);
            if (children.length) r.push(Object.assign({}, o, { children }));
        }
        return r;
    };

var data = [{ ID: 16, ItemName: "SomeData 1", children: [] }, { ID: 19, ItemName: "SomeData 2", children: [{ ID: 51, ItemName: "SomeData 3" }, { ID: 41, ItemName: "SomeData 4" }, { ID: 16, ItemName: "SomeData 5" }] }, { ID: 14, ItemName: "SomeData 4", children: [{ ID: 21, ItemName: "SomeData 9" }] }],
    search = 'SomeData 4',
    result = data.reduce(find, []);

console.log(result);
0 голосов
/ 27 января 2020

Вы можете пройти свой массив рекурсивно:

const search = (arr, keyWord) => {
  arr.forEach(element => {
    if ((element.ItemName == keyWord && element.children)) {
        searchResult.push(element);
    }

    if ((element.children && element.children.some(s=> s.ItemName == keyWord))) {
        let newObj = {...element};
        newObj.children = newObj.children.filter(f => f.ItemName == keyWord);
        searchResult.push(newObj);
    }

    if ( Array.isArray(element.children) && element.children.length > 0) {
        search(element.children, keyWord);
    }
  });
}

Пример:

let arr = [
  { ID: 16, ItemName: "SomeData 1", children: [] },
  { ID: 19, ItemName: "SomeData 2", children: [{ ID: 51, ItemName: "SomeData 3" }, { ID: 41, ItemName: "SomeData 4" }, { ID: 16, ItemName: "SomeData 5" }] },
  { ID: 14, ItemName: "SomeData 4", children: [{ ID: 21, ItemName: "SomeData 9" }] }];

let searchResult = [];
let wordToFind = 'SomeData 4';

const search = (arr, keyWord) => {
  arr.forEach(element => {
    if ((element.ItemName == keyWord && element.children)) {
        searchResult.push(element);
    }

    if ((element.children && element.children.some(s=> s.ItemName == keyWord))) {
        let newObj = {...element};
        newObj.children = newObj.children.filter(f => f.ItemName == keyWord);
        searchResult.push(newObj);
    }

    if ( Array.isArray(element.children) && element.children.length > 0) {
        search(element.children, keyWord);
    }
  });
}

search(arr, 'SomeData 4');
console.log(searchResult);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...