If typed "PCP DIST2"
, you want to Filter the elements you have both tags "PCP" and "DIST2", or may be the elements that have at least one of them?
Regardless of the criteria, one way to solve is to first break the tags in an array, using split
(but first use toLowerCase()
to turn them into tiny, because I saw that you want to do the consultation case insensitive, besides trim()
to remove the spaces from the beginning and end of the string, otherwise the split
return empty strings in the array):
let val = 'PCP DIST2';
let valores = val.trim().toLowerCase().split(' ');
console.log(valores); // ["pcp", "dist2"]
// se estiver separado por mais de um espaço, use:
val = ' PCP DIST2 ';
valores = val.trim().toLowerCase().split(/\s+/);
console.log(valores); // ["pcp", "dist2"]
Then we have to decide the criterion. If we want to verify that both tags are in the array, we have to use every
(which checks that all elements meet the criteria). But if we want any of the tags (
but not necessarily all) are in the array, we use some
(that checks if any of the elements meet the criterion). And to check if the element is in the array, we use includes
. Some examples:
let val = 'PCP DIST2';
let valores = val.trim().toLowerCase().split(' ');
// verificando se todas as tags estão no array
// array contém PCP e DIST2
console.log(valores.every(valor => ['PCP', 'ABC', 'DIST2'].map(s => s.toLowerCase()).includes(valor))); // true
// array contém PCP, mas não DIST2
console.log(valores.every(valor => ['PCP', 'ABC', 'DIST1'].map(s => s.toLowerCase()).includes(valor))); // false
// array não contém PCP nem DIST2
console.log(valores.every(valor => ['PC', 'ABC', 'DIST1'].map(s => s.toLowerCase()).includes(valor))); // false
// verificando se alguma das tags está no array
// array contém PCP, mas não DIST2
console.log(valores.some(valor => ['PCP', 'ABC', 'DIST1'].map(s => s.toLowerCase()).includes(valor))); // true
// array contém DIST2, mas não PCP
console.log(valores.some(valor => ['PC', 'ABC', 'DIST2'].map(s => s.toLowerCase()).includes(valor))); // true
// array não contém PCP nem DIST2
console.log(valores.some(valor => ['PC', 'ABC', 'DIST1'].map(s => s.toLowerCase()).includes(valor))); // false
That is, for all search values, I check that all (or any of them, depending on the criteria) are in the tag array.
Of course you could use indexOf
, which returns the index of the element (or -1 if it does not exist in the array), but as you only want to know if the element exists or not, use includes
is more direct because it returns only true
or false
.
Another detail is that filter
returns an empty array if no element satisfies the criterion is found. Then you should check that the returned array is empty before adding it to the results.
Then in your case:
// para verificar se todas as tags estão no array
this.portais.forEach( (e: Empresa) => {
var novoElemento = Object();
novoElemento.Name = e.Name;
novoElemento.Portais = e.Portais.filter(item => valores.every(valor => item.tags.map(s => s.toLowerCase()).includes(valor)));
if (novoElemento.Portais.length > 0) { // só insiro se encontrou algum
this.output_portais.push(novoElemento);
}
});
// para verificar se alguma das tags está no array
this.portais.forEach( (e: Empresa) => {
var novoElemento = Object();
novoElemento.Name = e.Name;
novoElemento.Portais = e.Portais.filter(item => valores.some(valor => item.tags.map(s => s.toLowerCase()).includes(valor)));
if (novoElemento.Portais.length > 0) { // só insiro se encontrou algum
this.output_portais.push(novoElemento);
}
});
Also note the use of map
to have the whole tag array in lowercase.
Filter more than one, you want to search both (AND) or any of the typed (OR)?
– Daniel Mendes