【问题标题】:JavaScript filter nested objects by property value [duplicate]JavaScript按属性值过滤嵌套对象[重复]
【发布时间】:2021-05-09 04:00:06
【问题描述】:

我有一个 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
         }
      ]
   }
]

【问题讨论】:

标签: javascript


【解决方案1】:

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;
}

【讨论】:

  • 在 Stackoverflow 上解释代码的如何为什么工作是一个很好的做法。你能向人们解释如何这是工作的吗?有些人可能知道它是如何工作的,但对于不知道的人来说,向他们解释是个好主意。
  • 当然@Reality。因此 filterList 函数将使用两个参数调用。类别 - 类别列表和关键字 - 搜索关键字。
  • 所以我的函数从类别列表中检查每个类别。对于每个类别,我通过 isHidden=false 参数和现有配置文件(包含关键字)过滤了子列表。我还将 toLocaleLowerCase 函数用于不区分大小写。如果该类别有一个符合要求的儿童,我推送到结果[],并为它覆盖儿童值。最后,函数返回所需类别的结果数组
  • @Cyber​​Eternal 运行时您的答案包含不包含旧的名称
  • @Cyber​​Eternal 我做到了..filterList(categories, 'old') 返回[{"category":"Players","children":[{"profiles":[{"name":"Kevin"},{"name":"Kevin Young"},{"name":"Kevin Old"}],"isHidden":false},{"profiles":[{"name":"Joe Old"}],"isHidden":false}]}].. 你可以看到几个存在的名称和没有关键字
【解决方案2】:

这专门回答了您的问题。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>

【讨论】:

  • 亲爱的@The Bomb Squad,你的函数的结果是错误的。它应该返回“children”数组中的两个项目,但返回 3 个项目。其中一个配置文件的名称不包含“旧”。
  • @Cyber​​Eternal 哦.. 对不起.. 编辑....
猜你喜欢
  • 2021-09-27
  • 1970-01-01
  • 2016-02-27
  • 2022-10-14
  • 1970-01-01
  • 2020-11-03
  • 2022-01-24
  • 2018-07-09
  • 2022-08-18
相关资源
最近更新 更多