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

multiselect filter array with nested object

我使用 vue-multiselect 让用户 select 项具有过滤选项:

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

谢谢你帮助我

原谅我大概的英语我是法国人

您可以递归地将对象展平为字符串数组,然后通过 Array.filter, Array.some & Array.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'))

您可以使用 Object.values to get the values of the object as an array, then use 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))

如果它可以帮助我找到一个实用的解决方案,请告诉我是否可以做一些更好的事情...

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

哇,谢谢你们!

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

如何看待我的发现?

此致