Array.prototype.filter - возможно ли отфильтровать несколько условий по нескольким критериям? [JS, VueJS] - PullRequest
0 голосов
/ 30 января 2020

У меня есть следующий метод для VueJS 2.0 / Nuxt Application:

applyFilters(filterCriteria) {
  this.filtered = this.unfiltered.slice().filter((x) => {
    // Zona
    if (x.zona !== filterCriteria.zona) {
      return false
    }

    // Bairro
    for (const key in filterCriteria.bairro) {
      if (x.bairro !== filterCriteria.bairro[key]) {
        return false
      }
    }

    // Categoria
    for (const key in filterCriteria.categoria) {
      if (x.categoria !== filterCriteria.categoria[key]) {
        return false
      }
    }
    return true
  })
},

Что я пытаюсь достичь, так это каким-то образом отфильтровать несколько условий, основанных также на нескольких критериях. Это достижимо с .filter()?

Когда бы я ни применял первый критерий, он работал нормально, а также, когда я применяю второй критерий, он будет работать также, но всякий раз, когда я применяю второй элемент ко второму критерию, он просто не удается отфильтровать и вернуться к false каждый раз.

Это работает:

  filterCriteria: {
    zona: 'Germany',
    bairro: ['Berlin'],
    categoria: ['City']
  }

Это не будет:

  filterCriteria: {
    zona: 'Germany',
    bairro: ['Berlin', 'Munich'],
    categoria: ['City']
  }

Я что-то упустил или это не будет работать, как ожидалось?

Ответы [ 2 ]

1 голос
/ 30 января 2020

Причина в том, что

for (const key in filterCriteria.bairro) {
  if (x.bairro !== filterCriteria.bairro[key]) {
    return false
  }
}

вы не можете иметь одно значение, равное двум различным значениям.

То есть, вы не можете иметь одно значение, равное 'Berlin' и тогда также равно 'Munich'. Так что точно не получится. Похоже, что у третьей проверки будет та же проблема.

Вы можете использовать includes, или другой способ -

if (!filterCriteria.bairro.some(v => v === x.bairro))
  return false;

и просто примечание: если у вас большой массив вместо этого вы можете использовать Set, чтобы проверка выполнялась быстро. Это как myCities.has(thisCity) и O(1) время.

1 голос
/ 30 января 2020

Вы можете использовать включает (). Массив и строка содержат этот метод

applyFilters(filterCriteria) {
    this.filtered = this.unfiltered.slice().filter((x) => {
        // Zona
        if (x.zona !== filterCriteria.zona) {
           return false
        }

        // Bairro
        if (!filterCriteria.bairro.includes(x.bairro)) {
           return false
        }

        // Categoria
        if (!filterCriteria.categoria.includes(x.categoria)) {
           return false
        }

        return true
    })
},
...