Lodash & Deepdash фильтр в дереве с функцией - PullRequest
0 голосов
/ 20 сентября 2019

У меня проблемы с lodash и deepdash, мне нужно отфильтровать дерево, сохраняя архитектуру parent / children, звучит просто, но я не могу заставить его работать

В настоящее время я фильтрую напервый уровень, он работает нормально:

let search = 'lor',
    data = [{
      name: 'Lorem',
      id: 1,
      children: [{
        name: 'Ipsum',
        id: 3
      }, {
        name: 'Dolor',
        id: 5
      }]
    },{
      name: 'Sit',
      id: 2
    }, {
      name: 'Lorem ipsum',
      id: 4
    }];


let fileterdData = _.filter(data, function (o) {
     return o.name.toLowerCase().includes(search);
});

Фильтры работают правильно, когда search = "lor";

Мне нужно отфильтровать на втором уровне, поэтому, если я ищу «ipsum», мне нужен отфильтрованный массив с id = 1 + его дочерний id = 3 (соответствует «ipsum») иid = 4 (соответствует «ipsum»).

Может ли кто-нибудь помочь?

Ответы [ 4 ]

0 голосов
/ 21 сентября 2019

, если вы все еще заинтересованы в решении Deepdash , вот пример для вашего случая:

let fileterdData = _.filterDeep(data,
  function (o) { return o.name.toLowerCase().includes('ipsum');},
  {childrenPath: 'children'});
0 голосов
/ 20 сентября 2019

Вы можете снова выполнить поиск по дочерним элементам, чтобы проверить, существует ли ключевое слово для поиска, как показано ниже:

const search = 'ips';
const datas = [{
      name: 'Lorem',
      id: 1,
      children: [{
        name: 'Ipsum',
        id: 3
      }, {
        name: 'Dolor',
        id: 5
      }]
    },{
      name: 'Sit',
      id: 2
    }, {
      name: 'Lorem',
      id: 4
    }];

const includesName = (name = '') => name.toLowerCase().includes(search);

let fileterdData = _.filter(datas, data => {
    const { children, name } = data;

    return (
        !_.isEmpty(children)
            ? !!_.filter(children, child => includesName(child.name))
            : includesName(name)
    );
});

console.log(fileterdData);
0 голосов
/ 20 сентября 2019

Работаем (спасибо Milind Agrawal) с некоторыми правками:

const includesName = (name = '') => name.toLowerCase().includes(search);

let filteredData = _.filter(data, data => {
    const { children, name } = data;
    return (
        !_.isEmpty(children)
            ? (
                !!_.filter(children, ({ name }) => includesName(name)).length ||
                includesName(name)
            )
            : includesName(name)
    );
});

В троице мы проверим, имеет ли родитель значение тоже + проверяет длину результатов, отфильтрованных детьми (не делает)т работать без него)

0 голосов
/ 20 сентября 2019

Вы должны сделать еще один фильтр уровня.Вот простой простой JS.измените свой код согласно lodash _.filter.

let search = 'lor',
    data = [{
      name: 'Lorem',
      id: 1,
      children: [{
        name: 'Ipsum',
        id: 3
      }, {
        name: 'Dolor',
        id: 5
      }]
    },{
      name: 'Sit',
      id: 2
    }, {
      name: 'Lorem ipsum',
      id: 4
    }];
    
 //   let fileterdData = _.filter(data, function (o) {
 //   if(o.children){
  // o.children = _.filter(o.children, function (c) {
// return c.name.toLowerCase().indexOf(search) > -1;
// });
//}
  //   return o.name.toLowerCase().includes(search);
//});


let fileterdData = data.filter(function (o) {
if(o.children){
o.children = o.children.filter((c)=>{
return c.name.toLowerCase().indexOf(search) > -1;
});
}

return o.name.toLowerCase().indexOf(search) > -1;
});

console.log(fileterdData);
...