múltiples condiciones para el método JavaScript .includes ()

95

Me pregunto, ¿hay alguna manera de agregar varias condiciones a un método .includes, por ejemplo:

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

Imagine los estados de coma "o".

Ahora pregunta si la cadena contiene hola, hola o hola . Entonces, solo si una, y solo una de las condiciones es verdadera.

¿Existe algún método para hacer eso?

usuario6234002
fuente
1
orimplicaría que al menos una coincidencia sería suficiente.
robertklep
En lugar de buscar la solución con el método incluye, puede probar indexOf así: ['hello', 'hi', 'howdy'].indexOf(str)
Skander Jenhani

Respuestas:

29

Eso debería funcionar incluso si una, y solo una de las condiciones es verdadera:

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
fuente
Solo una nota. Cualquiera que intente esto en Google Apps Script obtendrá un TypeError: stackoverflow.com/questions/51291776/…
Kurt Leadley
193

Puede utilizar el .somemétodo al que se hace referencia aquí .

El some()método prueba si al menos un elemento de la matriz pasa la prueba implementada por la función proporcionada.

// 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
fuente
3
Nota importante: some()es un método, no un operador. De lo contrario, buena respuesta.
Mitya
Punto a favor. Gracias
dinigo
Esta debería ser la respuesta aceptada
matebende
26

Con includes(), no, pero puedes lograr lo mismo con REGEX a través de test():

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

O, si las palabras provienen de una fuente dinámica:

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

El enfoque REGEX es una mejor idea porque le permite hacer coincidir las palabras como palabras reales, no como subcadenas de otras palabras. Solo necesita la palabra marcador de límite \b, así que:

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
Mitia
fuente
Esto no funcionará si las palabras contienen caracteres especiales de expresión regular. Además, esto no satisfará el requisito aparente del OP de que coincida solo si hay una coincidencia con una sola palabra.
17

También puedes hacer algo como esto:

const str = "hi, there"

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

console.log(res);

Siempre que una de sus inclusiones devuelva verdadero, el valor será verdadero; de lo contrario, será falso. Esto funciona perfectamente bien con ES6.

Thomas Leclerc
fuente
OP dijo: "Entonces, solo si una, y solo una de las condiciones es verdadera". Su fragmento devolverá verdadero para una cadena que contiene las tres palabras, donde OP querría que devuelva falso.
Dane Brouwer
4

Eso se puede hacer usando algunos / todos los métodos de Array y RegEx.

Para verificar si TODAS las palabras de la lista (matriz) están presentes en la cadena:

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 si ALGUNA de las palabras de la lista (matriz) están presentes en la cadena:

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
fuente
Guau. esto respondió a mis dos preguntas. ¡¡¡¡Muchas gracias!!!!
BoundForGlory
2

No es la mejor respuesta ni la más limpia, pero creo que es más permisiva. Por ejemplo, si desea utilizar los mismos filtros para todos sus cheques. En realidad, .filter()funciona con una matriz y devuelve una matriz filtrada (que también encuentro más 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
fuente
2

Aquí hay una opción controvertida :

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

Permitiéndote hacer cosas como:

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

¡Otro!

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
fuente
-1

Extendiendo el prototipo 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);
        }
    });
}

Permitiéndote hacer cosas como:

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

¿Qué tal ['hello', 'hi', 'howdy'].includes(str)?

neatsu
fuente
1
No, no funciona: ['hello', 'hi', 'howdy'].includes('hello, how are you ?')devuelve false, mientras que OP solicita una solución que devuelve true.
Basj