过滤嵌套数组时保留数组结构

时间:2021-06-13 08:37:28

标签: javascript arrays filter

我的大脑被这种高​​级过滤器冻结了。这个任务已经超出了我对filtermap等的基本知识

这里我有一个带有数组的嵌套对象的数组:

const DATA = [
    {
        title: 'Spongebob',
        data: [
            { id: 1, name: 'Mr Crabs' },
            { id: 2, name: 'Sandy' }
        ]
    },
    {
        title: 'Dragon Balls Z',
        data: [
            { id: 1, name: 'GoKu' },
            { id: 2, name: 'Zamasu' }
        ]
    }
];

如果您曾与 React Native (RN) 合作过,您可能已经见过这种风格。这个问题不适合RN。我需要对嵌套数组中的 name 属性执行过滤器,当我得到匹配项时,我必须将格式作为 DATA 变量返回。

const handleFiltering = (value) => {

    const _value = value.toLowerCase();

    const results = DATA.map(o => {
        return o.data.filter(o => o.name.toLowerCase().indexOf(_value) != -1)
    });

    console.log(results);
};

我对深度过滤的有限了解返回了 data 数组的基本过滤,但需要保留 DATA 的结构。我期望的预期结果:


// I'm now querying for "ZAMASU"

const handleFiltering = (value='ZAMA') => {

    const _value = value.toLowerCase();

    const results = DATA.map(o => {
        return o.data.filter(o => o.name.toLowerCase().indexOf(_value) != -1)
    });

    // console.log(results) should now be
    // [
    //  {
    //      title: 'Dragon Balls Z',
    //     data: [
    //          { id: 2, name: 'Zamasu' }
    //      ]
    //  }
    // ];
};

想到的是使用 {...DATA, something-here } 但我的大脑已经冻结,因为我需要取回 title 属性。请问如何实现?

2 个答案:

答案 0 :(得分:1)

您可以使用数组的 reduce 方法。首先找出数据数组中的对象,然后通过保留原始结构将其作为新条目添加到累加器数组中。

const DATA = [
    {
        title: 'Spongebob',
        data: [
            { id: 1, name: 'Mr Crabs', where: 'tv' },
            { id: 2, name: 'Sandy' }
        ]
    },
    {
        title: 'Dragon Balls Z',
        data: [
            { id: 1, name: 'GoKu' },
            { id: 2, name: 'Zamasu' }
        ]
    }
];


let handleFiltering = (value='tv') => {
 return DATA.reduce((acc,d) => {
           let obj = d.data.find(a => a.name?.toLowerCase().includes(value.toLowerCase()) 
|| a.where?.toLowerCase().includes(value.toLowerCase()));
           obj ? acc.push({...d, data:[obj]}) : null; 
           return acc;
    }, []);
}

let result = handleFiltering();

console.log(result);

答案 1 :(得分:1)

另一种解决方案是首先使用过滤器在通过参数传递的数据中仅查找包含名称的对象,然后映射数据。

这是您调整后的过滤方法

const handleFiltering = (value) => {
  const _value = value.toLowerCase();

  const results = DATA.filter((obj) =>
    obj.data.some((character) => character.name.toLowerCase() === _value)
  ).map((obj) => ({
    title: obj.title,
    data: obj.data.filter(
      (character) => character.name.toLowerCase() === _value
    ),
  }));

  console.log(results);
};