várias condições para o método JavaScript .includes ()

101

Apenas pensando, há uma maneira de adicionar várias condições a um método .includes, por exemplo:

    var value = str.includes("hello", "hi", "howdy");

Imagine os estados de vírgula "ou".

Ele está perguntando agora se a string contém hello, hi ou howdy. Portanto, apenas se uma e apenas uma das condições for verdadeira.

Existe um método para fazer isso?

user6234002
fonte
1
orimplicaria que pelo menos uma correspondência seria suficiente.
robertklep
1
Em vez de procurar a solução com o método includes, você pode tentar o indexOf assim: ['hello', 'hi', 'howdy'].indexOf(str)
Skander Jenhani
@SkanderJenhani pelo menos leia e experimente antes de comentar. Sua sugestão sempre retornará-1
chankruze
2
o que pode ser feito &&?
arora

Respostas:

30

Isso deve funcionar mesmo que uma, e apenas uma das condições seja verdadeira:

var str = "bonjour le monde vive le javascript";
var arr = ['bonjour','europe', 'c++'];

function contains(target, pattern){
    var value = 0;
    pattern.forEach(function(word){
      value = value + target.includes(word);
    });
    return (value === 1)
}

console.log(contains(str, arr));
Kevin Ternet
fonte
Apenas uma nota. Qualquer um que tentar isso no Google Apps Script receberá um TypeError: stackoverflow.com/questions/51291776/…
Kurt Leadley
207

Você pode usar o .somemétodo referenciado aqui .

O some()método testa se pelo menos um elemento da matriz passa no teste implementado pela função fornecida.

// test cases
var str1 = 'hi, how do you do?';
var str2 = 'regular string';

// do the test strings contain these terms?
var conditions = ["hello", "hi", "howdy"];

// run the tests against every element in the array
var test1 = conditions.some(el => str1.includes(el));
var test2 = conditions.some(el => str2.includes(el));

// display results
console.log(str1, ' ===> ', test1);
console.log(str2, ' ===> ', test2);

dinigo
fonte
3
Observação: some()é um método, não um operador. Caso contrário, boa resposta.
Mitya
Ponto tomado. Obrigado
dinigo
26

Com includes(), não, mas você pode conseguir o mesmo com REGEX via test():

var value = /hello|hi|howdy/.test(str);

Ou, se as palavras vierem de uma fonte dinâmica:

var words = array('hello', 'hi', 'howdy');
var value = new RegExp(words.join('|')).test(str);

A abordagem REGEX é uma ideia melhor porque permite que você combine as palavras como palavras reais, não substrings de outras palavras. Você só precisa do marcador de limite de palavra \b, então:

var str = 'hilly';
var value = str.includes('hi'); //true, even though the word 'hi' isn't found
var value = /\bhi\b/.test(str); //false - 'hi' appears but not as its own word
Mitya
fonte
Isso não funcionará se as palavras contiverem caracteres regexp especiais. Além disso, isso não satisfará o aparente requisito do OP de correspondência apenas se houver correspondência com uma única palavra.
17

Você também pode fazer algo assim:

const str = "hi, there"

const res = str.includes("hello") || str.includes("hi") || str.includes('howdy');

console.log(res);

Sempre que um de seus includes retornar verdadeiro, o valor será verdadeiro, caso contrário, será falso. Isso funciona perfeitamente bem com ES6.

Thomas Leclerc
fonte
OP disse: "Portanto, apenas se uma e apenas uma das condições for verdadeira." Seu snippet retornará verdadeiro para uma string que contém todas as três palavras, onde OP gostaria que ele retornasse falso.
Dane Brouwer
4

Isso pode ser feito usando alguns / todos os métodos de Array e RegEx.

Para verificar se TODAS as palavras da lista (matriz) estão presentes na string:

const multiSearchAnd = (text, searchWords) => (
  searchWords.every((el) => {
    return text.match(new RegExp(el,"i"))
  })
)

multiSearchAnd("Chelsey Dietrich Engineer 2018-12-11 Hire", ["cle", "hire"]) //returns false
multiSearchAnd("Chelsey Dietrich Engineer 2018-12-11 Hire", ["che", "hire"]) //returns true

Para verificar se QUALQUER uma das palavras da lista (matriz) está presente na string:

const multiSearchOr = (text, searchWords) => (
  searchWords.some((el) => {
    return text.match(new RegExp(el,"i"))
  })
)

multiSearchOr("Chelsey Dietrich Engineer 2018-12-11 Hire", ["che", "hire"]) //returns true
multiSearchOr("Chelsey Dietrich Engineer 2018-12-11 Hire", ["aaa", "hire"]) //returns true
multiSearchOr("Chelsey Dietrich Engineer 2018-12-11 Hire", ["che", "zzzz"]) //returns true
multiSearchOr("Chelsey Dietrich Engineer 2018-12-11 Hire", ["aaa", "1111"]) //returns false
Denys Rusov
fonte
Uau. isso respondeu minhas duas perguntas. Muito obrigado !!!!
BoundForGlory
2

Não é a melhor resposta e não é a mais limpa, mas acho que é mais permissiva. Por exemplo, se você quiser usar os mesmos filtros para todos os seus cheques. Na verdade .filter()funciona com um array e retorna um array filtrado (que também acho mais fácil de usar).

var str1 = 'hi, how do you do?';
var str2 = 'regular string';
var conditions = ["hello", "hi", "howdy"];

// Solve the problem
var res1 = [str1].filter(data => data.includes(conditions[0]) || data.includes(conditions[1]) || data.includes(conditions[2]));
var res2 = [str2].filter(data => data.includes(conditions[0]) || data.includes(conditions[1]) || data.includes(conditions[2]));

console.log(res1); // ["hi, how do you do?"]
console.log(res2); // []


// More useful in this case
var text = [str1, str2, "hello world"];

// Apply some filters on data
var res3 = text.filter(data => data.includes(conditions[0]) && data.includes(conditions[2]));
// You may use again the same filters for a different check
var res4 = text.filter(data => data.includes(conditions[0]) || data.includes(conditions[1]));

console.log(res3); // []
console.log(res4); // ["hi, how do you do?", "hello world"]
Romingo
fonte
2

Esta é uma opção controversa :

String.prototype.includesOneOf = function(arrayOfStrings) {
  if(!Array.isArray(arrayOfStrings)) {
    throw new Error('includesOneOf only accepts an array')
  }
  return arrayOfStrings.some(str => this.includes(str))
}

Permitindo que você faça coisas como:

'Hi, hope you like this option'.toLowerCase().includesOneOf(["hello", "hi", "howdy"]) // True
James Broad
fonte
1

Outro!

let result

const givenStr = 'A, X' //values separated by comma or space.

const allowed  = ['A', 'B']
const given    = givenStr.split(/[\s,]+/).filter(v => v)

console.log('given (array):', given)

// given contains none or only allowed values:

result = given.reduce((acc, val) => {
  return acc && allowed.includes(val)
}, true)

console.log('given contains none or only allowed values:', result)

// given contains at least one allowed value:

result = given.reduce((acc, val) => {
  return acc || allowed.includes(val)
}, false)

console.log('given contains at least one allowed value:', result)

lsblsb
fonte
-1

Extensão de protótipo nativo de string:

if (!String.prototype.contains) {
    Object.defineProperty(String.prototype, 'contains', {
        value(patterns) {
            if (!Array.isArray(patterns)) {
                return false;
            }

            let value = 0;
            for (let i = 0; i < patterns.length; i++) {
                const pattern = patterns[i];
                value = value + this.includes(pattern);
            }
            return (value === 1);
        }
    });
}

Permitindo que você faça coisas como:

console.log('Hi, hope you like this option'.toLowerCase().contains(["hello", "hi", "howdy"])); // True
iProDev
fonte
-2

Que tal ['hello', 'hi', 'howdy'].includes(str)?

neatsu
fonte
1
Não, não funciona: ['hello', 'hi', 'howdy'].includes('hello, how are you ?')retorna false, enquanto OP pede uma solução que retorna true.
Basj,