Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

153
Visualizações
Filtering an array by multiple property values

I have an array of the form

var cars = [
   {name: "BMW X5", topsales: ["USA", "China", "Russia"], maxspeed: 250, users: ["teenage", "ladies", "mens"]}
   {name: "Volkswagen Touareg", topsales: ["USA", "Germany"], maxspeed: 240, users: ["teenage", "mens", "old mens"]}
   etc....
]

I am trying to filter, let's say like this:

var query = {
   topsales: ["USA", "China"],
   users: "teenage"
}
function nestedFilter(targetArray, filters) {
     var filterKeys = Object.keys(filters);
     return targetArray.filter(function (eachObj) {
         return filterKeys.every(function (eachKey) {
             if (!filters[eachKey].length) {
                 return true; 
             }
             return filters[eachKey].includes(eachObj[eachKey]);
          });
     });
};
goodresult = nestedFilter(cars, query);

But the function doesn't work as it should. If the object has one value in the property, then it filters, but if there are several of them, and I need at least one of them to satisfy the search, then it does not filter. Help who can please

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

You can check if the value of the "filterKey" is not an array, make it an array, and check if an array has a subArray

function hasSubArray(master, sub) {
  return sub.every((i => v => i = master.indexOf(v, i) + 1)(0));
}

function nestedFilter(targetArray, filters) {
  var filterKeys = Object.keys(filters);
  return targetArray.filter(function (eachObj) {
    return filterKeys.every(function (eachKey) {
      var subArray = filters[eachKey];
      if (!Array.isArray(filters[eachKey])) {
        subArray = [filters[eachKey]];
      }

      return hasSubArray(eachObj[eachKey], subArray);
    });
  });
}
about 4 years ago · Juan Pablo Isaza Relatório

0

I am assuming that you intend to implement an OR functionality because you said at least one of them. Therefore the working code is below.

But before going on reading, please beware of below remarks:

  • I used some instead of every, because some works as or and every works as and. It means that that line will return true if the current car item matches at least one of the filters.

  • You should use item.includes(filter) instead of filter.includes(item).

  • You need to check if the current filter item is an array or not, and act accordingly.

  • In this code I didn't handle that and assumed that currentCandidate is a string or a primitive. If there are other cases where the candidate item (i.e. a field of the car) itself is also an array, then you have to update the code to also handle that.


  var cars = [
    {name: "BMW X5", topsales: "USA, China, Russia", maxspeed: 250, users: "teenage, ladies, men"},
    {name: "Volkswagen Touareg", topsales: "USA, Germany", maxspeed: 240, users: "teenage, men, old men"}
  ]
  
  var query = {
    topsales: ["USA", "China"],
    maxspeed: 240
  }
  
  function nestedFilter(targetArray, filters) {
    const filterKeys = Object.keys(filters);
    return targetArray.filter(function (eachObj) {
      //using some instead of every to make sure that it works as OR
      const result = filterKeys.some(function (eachKey) {
        //the current item that we are trying to use in the filter
        const currentCandidate = eachObj[eachKey];
  
        //the current item that we are using as a filter
        const currentFilterItem = filters[eachKey]
  
        if (Array.isArray(currentFilterItem)) {
          if (currentFilterItem.length === 0) {
            //no filter, return true
            return true
          }
  
          //loop on each item in the currentFilterItem
          //if any of them matches simply return true (OR)
          for (let filterKey in currentFilterItem) {
            if (currentCandidate.includes(currentFilterItem[filterKey])) {
              return true
            }
          }
          //for loop ended, no match
          return false
        } else {
          //the current filter item is not an array, use it as one item
          //return eachObj[eachKey].includes(currentFilterItem)
          return currentCandidate === currentFilterItem
        }
      });
  
      return result;
    });
  }
  
  goodresult = nestedFilter(cars, query);
  console.debug(goodresult)
about 4 years ago · Juan Pablo Isaza Relatório

0

You could check if query is an array and/or the value is an array and check accordingly.

function nestedFilter(data, query) {
    const
        filters = Object.entries(query);

    return data.filter(o => filters.every(([k, v]) => Array.isArray(v)
        ? Array.isArray(o[k])
            ? v.some(s => o[k].includes(s))
            : v.includes(o[k])
        : Array.isArray(o[k])
            ? o[k].includes(v)
            : o[k] === v
    ));
}

const
    cars = [{ name: "BMW X5", topsales: ["USA", "China", "Russia"], maxspeed: 250, users: ["teenage", "ladies", "mens"] }, { name: "Volkswagen Touareg", topsales: ["USA", "Germany"], maxspeed: 240, users: ["teenage", "mens", "old mens"] }],
    query = { topsales: ["USA", "China"], users: "teenage" };

console.log(nestedFilter(cars, query));

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda