Home > Enterprise >  filter array in object and another object attribute at the same time
filter array in object and another object attribute at the same time

Time:07-13

this is the problem, I need to filter "header" attribute and content at the same time, this is data structure:

const testData = [
        {
            header: '公众号',
            content: [{ name: '系統公告'}],
        },
        {
            header: '我的群聊',
            content: [{ name: 'test01'}, { name: '下'}, { name: '公级用户'}],
        },
        {
            header: '上级用户',
            content: [{ username: 'root' }],
        },
        {
            header: '下级用户',
            content: [{ name: 'test0301'}, { name: '1234'},],
        },
    ];

and if I input something like "下", data should show like this:

const testData = [
        {
            header: '我的群聊',
            content: [{ name: '下'}],
        },
        {
            header: '下级用户',
            content: [{ name: 'test0301'}, { name: '1234'},],
        },
    ];

if I input something like "我", data should show like this:

const testData = [
        {
            header: '我的群聊',
            content: [{ name: 'test01'}, { name: '下'}, { name: '公级用户'}],
        },
];

i just spend ten hours to think this, but i dont have any ideas......

CodePudding user response:

you can do something like this using Array.reduce

const filterData = (data, search) => data.reduce((res, item) => {
  if(item.header.includes(search)){
    return [
      ...res,
      item
    ]
  }
  const content = item.content.filter(({name}) => name && name.includes(search))
  
  if(content.length > 0){
    return [
     ...res,
     {...item, content}
    ]
  }
  
  
  return res

}, [])



const testData = [
        {
            header: '公众号',
            content: [{ name: '系統公告'}],
        },
        {
            header: '我的群聊',
            content: [{ name: 'test01'}, { name: '下'}, { name: '公级用户'}],
        },
        {
            header: '上级用户',
            content: [{ username: 'root' }],
        },
        {
            header: '下级用户',
            content: [{ name: 'test0301'}, { name: '1234'},],
        },
    ];
    
 console.log(filterData(testData, '下' ))
 console.log(filterData(testData, '我' ))
 

CodePudding user response:

Here is a solution that should solve your probleme :

const input = '下';

let result = testData.filter(data => {
    return (
        data.header.includes(input)
         || 
        data.content.some( el => Object.keys(el).map(key => el[key].includes(input) ).some(el => el === true) )
    );
});

console.log(result);

// Output
// [
//  {
//         "header": "我的群聊",
//         "content": [ { "name": "test01" }, { "name": "下" },  { "name": "公级用户" } ]
//     },
//     {
//         "header": "下级用户",
//         "content": [ { "name": "test0301" }, { "name": "1234" } ]
//     }
// ]

or using 2 function :

let filterHeader = function(data, input) {
    return data.filter(d => d.header.includes(input));
}

let filterContent = function(data, input) {
    return data.filter(d => d.content.some( el => Object.keys(el).map(key => el[key].includes(input) ).some(el => el === true) ));
}

console.log(filterHeader(testData, input));
console.log(filterContent(testData, input));
  • Related