многоотборный массив фильтров с вложенным объектом - PullRequest
0 голосов
/ 16 ноября 2018

Я использую 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 голосов
/ 16 ноября 2018

вау спасибо вам обоим!

эта техника кажется действительно интересной ... но позвольте мне некоторое время понять ее

что вы думаете о том, что я нашел?

С наилучшими пожеланиями

0 голосов
/ 16 ноября 2018

Вы можете использовать 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))
0 голосов
/ 16 ноября 2018

если это может помочь, я думаю, что нашли функциональное решение, дайте мне знать, если что-то может быть лучше ...

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}
})
0 голосов
/ 16 ноября 2018

Вы можете рекурсивно сгладить объекты в массив строк, а затем искать их с помощью 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'))
...