JavaScript 按属性值过滤嵌套对象

时间:2021-02-04 19:35:18

标签: javascript

我在 JavaScript 中有一个嵌套的对象列表,我想使用“搜索字符串”和属性值来过滤它们。

我只想收集具有未隐藏的儿童且至少包含一个名称中包含搜索关键字的个人资料的类别。我不太确定如何利用 JavaScript 的花里胡哨来编写函数本身。

下面是伪代码

初始列表:

categories = [
   {
      "category":"Players",
      "children":[
         {
            "profiles":[
               {
                  "name":"Kevin"
               },
               {
                  "name":"Kevin Young"
               },
               {
                  "name":"Kevin Old"
               }
            ],
            "isHidden":false
         },
         {
            "profiles":[
               {
                  "name":"Mike"
               },
               {
                  "name":"Mike Baby"
               }
            ],
            "isHidden":false
         },
         {
            "profiles":[
               {
                  "name":"Joe Old"
               }
            ],
            "isHidden":false
         }
      ]
   },
   {
      "category":"Teams",
      "children":[
         {
            "profiles":[
               {
                  "name":"Cowboys"
               }
            ],
            "isHidden":true
         },
         {
            "profiles":[
               {
                  "name":"Steelers"
               }
            ],
            "isHidden":false
         }
      ]
   }
]

伪函数:

filterList: function(): Categories[] {
   return categories.filter((cat: Category): boolean => {
      // loop through each categories list of children

      // if child is hidden skip the child item
      // if child's profiles do not contain the word 'old' (Caseinsensitive) skip child

      // lastly do not return a category in the return if there are no children
      // after filtering them based on the conditions above

      // if category contains one or more children after children
   });
 }

功能结果:

categories = [
   {
      "category":"Players",
      "children":[
         {
            "profiles":[
               {
                  "name":"Kevin"
               },
               {
                  "name":"Kevin Young"
               },
               {
                  "name":"Kevin Old"
               }
            ],
            "isHidden":false
         },
         {
            "profiles":[
               {
                  "name":"Joe Old"
               }
            ],
            "isHidden":false
         }
      ]
   }
]

2 个答案:

答案 0 :(得分:0)

这专门回答了您的问题.. filter 的工作原理是,当您为该索引返回 false 时不返回该数组的索引

此外,我复制对象而不是直接使用它因为在过滤时我在嵌套的更深层编辑属性(充当深层过滤器)

//I am copying the array taken in to avoid data loss from original object

function doIt(arr,word){
  try{arr=JSON.parse(JSON.stringify(arr))}
  catch(err){throw Error(err)}
  return arr.filter(a=>{
    var toReturn=true
    a.children.forEach(b=>{
      if(!b.profiles.length||b.isHidden){return toReturn=false} //filters out the lvl 1 elements not meeting requirements and if it is to be filtered out, unnecesary steps below are avoided
      var tempArr=[] //for "whitelisting" since only the indexes that include [word] are to be apart of the profiles
      b.profiles.forEach((c,i)=>{ //checking and valid results are pushed into the array
        if(c.name.toLowerCase().includes(word)){tempArr.push(c)}
      })
      b.profiles=tempArr //linking complete
      if(!tempArr.length){delete(b.profiles)} //if nothing in an array has a valid value, removal
    })
    return toReturn
  })
}

console.log(doIt(categories,'old'))
<script>
categories = [ //it's a global on purpose
   {
      "category":"Players",
      "children":[
         {
            "profiles":[
               {
                  "name":"Kevin"
               },
               {
                  "name":"Kevin Young"
               },
               {
                  "name":"Kevin Old"
               }
            ],
            "isHidden":false
         },
         {
            "profiles":[
               {
                  "name":"Mike"
               },
               {
                  "name":"Mike Baby"
               }
            ],
            "isHidden":false
         },
         {
            "profiles":[
               {
                  "name":"Joe Old"
               }
            ],
            "isHidden":false
         }
      ]
   },
   {
      "category":"Teams",
      "children":[
         {
            "profiles":[
               {
                  "name":"Cowboys"
               }
            ],
            "isHidden":true
         },
         {
            "profiles":[
               {
                  "name":"Steelers"
               }
            ],
            "isHidden":false
         }
      ]
   }
]
</script>

答案 1 :(得分:0)

filterList 函数将使用两个参数调用。类别 - 类别列表,以及关键字 - 搜索关键字。所以我的函数检查类别列表中的每个类别。对于每个类别,我通过 isHidden=false 参数以及包含关键字的名称的现有配置文件过滤了孩子的列表。我还使用 toLocaleLowerCase 函数来区分大小写。如果类别有满足要求的儿童,我推到结果[],并覆盖其儿童值。最后,该函数返回具有所需类别的结果数组

const filterList = (categories, keyword) => {
  const kwd = keyword.toLocaleLowerCase()
  const result = [];
  for (const cat of categories) {
    const children = cat.children.filter(i => !i.isHidden && i.profiles.some(j => j.name.toLocaleLowerCase().includes(kwd)));
    if (children.length) result.push({ ...cat, children })
  }
  return result;
}
相关问题