具有嵌套对象的多选过滤器数组

时间:2018-11-16 17:23:17

标签: javascript arrays filter nested multi-select

我使用vue-multiselect来让用户选择带有过滤选项的项目:

query = "what user type in input field"
allLinks.filter(l=>l.labelName.includes(query))

它可以工作,但是现在我想使用这种结构将过滤扩展到对象的所有属性:

{
    "labelName":"LK000056",
    "extPort":{
        "aPort":"EXTA-EQ001/board10port02",
        "zPort":"EXTZ-EQ012/board09port02"
    }
}

如果查询在labelName,aPort或zPort上匹配,我希望使用一个查询来获取父对象。

有可能吗?或以类似

的条件方式
allLinks.filter(l=>if(!l.labelName.includes(query)){l.extport.aPort.includes(query)}else{l.extport.zPort.includes(query)})

感谢您的帮助

请原谅我大约英语我是法语

4 个答案:

答案 0 :(得分:0)

您可以递归地将对象展平为字符串数组,然后通过Array.filterArray.someArray.includes进行搜索:

const data = [{ "labelName":"LK000056", "extPort":{ "aPort":"EXTA-EQ001/board10port02", "zPort":"EXTZ-EQ012/board09port02" } }, { "labelName":"LK000057", "extPort":{ "aPort":"EXTA-EQ001/board123", "zPort":"EXTZ-EQ012/board333" } }]

const flatten = (obj, a=[]) => Object.values(obj)
  .reduce((r,c) => (typeof c == 'object' ? flatten(c,a) : r.push(c), r), a)

const search = (d, t) => 
  d.filter(x => flatten(x).some(x => x.toLowerCase().includes(t.toLowerCase())))

console.log(search(data, 'board123'))
console.log(search(data, 'LK000056'))
console.log(search(data, 'EXTZ-EQ012'))

请注意,这是通用方法,并且无论data的嵌套级别如何都可以使用,例如:

const data = [{
  "A": {
    "B": {
      "C": {
        "data": '11'
      },
    }
  }
}, {
  "D": {
    "E": {
      "data": '22'
    }
  }
}, {
  "F": "33"
}]

const flatten = (obj, a = []) => Object.values(obj)
  .reduce((r, c) => (typeof c == 'object' ? flatten(c, a) : r.push(c), r), a)

const search = (d, t) => d.filter(x => 
  flatten(x).some(x => x.toLowerCase().includes(t.toLowerCase())))

console.log(search(data, '22'))
console.log(search(data, '11'))
console.log(search(data, '33'))

答案 1 :(得分:0)

您可以使用Object.values以数组的形式获取对象的值,然后使用some测试一个或多个项目是否匹配。

const items = [{
  "labelName": "LK000056",
  "extPort": {
    "aPort": "EXTA-EQ001/board10port02",
    "zPort": "EXTZ-EQ012/board09port02"
  }
}, {
  "labelName": "234234",
  "extPort": {
    "aPort": "abc123",
    "zPort": "1234567890"
  }
}]

function search(query, data) {
  return data.filter(i => {
    if (i.labelName.includes(query)) return true
    if (Object.values(i.extPort).some(v => v.includes(query))) return true
    return false
  })
}

console.log(search("EQ001", items))
console.log(search("1234567890", items))
console.log(search("lalalala", items))

答案 2 :(得分:0)

如果它可以帮助我认为找到了功能解决方案,请告诉我是否可以做得更好...

allLinks.filter(l=>{
    if (l.sdhPort.zSDHPort!=undefined && l.extPort.aPort.toUpperCase().includes(query.toUpperCase())){return true}
    if (l.extport.zPort!=undefined && l.extPort.zPort.toUpperCase().includes(query.toUpperCase())){return true}
    if (l.labelName!=undefined && l.labelName.toUpperCase().includes(query.toUpperCase())){return true}
})

答案 3 :(得分:0)

哇,谢谢你们!

这项技术看起来真的很有趣...但是让我花点时间了解它

我如何看待我发现的东西?

最好的问候