wiele warunków dla metody JavaScript .includes ()

101

Zastanawiam się tylko, czy istnieje sposób na dodanie wielu warunków do metody .includes, na przykład:

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

Wyobraź sobie, że przecinek oznacza „lub”.

Pyta teraz, czy ciąg zawiera cześć, cześć czy cześć . Więc tylko wtedy, gdy jeden i tylko jeden z warunków jest spełniony.

Czy jest na to metoda?

user6234002
źródło
1
oroznaczałoby, że przynajmniej jedno dopasowanie byłoby wystarczające.
robertklep
1
Zamiast szukać rozwiązania za pomocą metody include, możesz wypróbować następujący ['hello', 'hi', 'howdy'].indexOf(str)
indeks
@SkanderJenhani przynajmniej przeczytaj i spróbuj przed skomentowaniem. Twoja sugestia zawsze wróci-1
chankruze
2
co można zrobić &&?
arora

Odpowiedzi:

30

To powinno zadziałać, nawet jeśli spełniony jest jeden i tylko jeden z warunków:

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
źródło
Tylko uwaga. Każdy, kto spróbuje tego w Google Apps Script, otrzyma TypeError: stackoverflow.com/questions/51291776/ ...
Kurt Leadley
207

Możesz użyć .somemetody, o której mowa tutaj .

Te some()testy metoda czy co najmniej jeden z elementów układu przechodzi test realizowane przez funkcję usług.

// 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
źródło
3
Uwaga: some()to metoda, a nie operator. W przeciwnym razie dobra odpowiedź.
Mitya
Punkt zajęty. Dziękuję
dinigo
26

Z includes(), nie, ale możesz osiągnąć to samo z REGEX poprzez test():

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

Lub, jeśli słowa pochodzą z dynamicznego źródła:

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

Podejście REGEX jest lepszym pomysłem, ponieważ pozwala dopasować słowa jako rzeczywiste słowa, a nie podciągi innych słów. Potrzebujesz tylko znacznika granicy słowa \b, więc:

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
źródło
To nie zadziała, jeśli słowa zawierają specjalne znaki wyrażenia regularnego. Ponadto nie spełni to oczywistego wymogu OP, który będzie pasował tylko wtedy, gdy istnieje dopasowanie z jednym słowem.
17

Możesz też zrobić coś takiego:

const str = "hi, there"

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

console.log(res);

Za każdym razem, gdy jedno z twoich obejmuje zwraca true, value będzie true, w przeciwnym razie będzie false. Działa to doskonale z ES6.

Thomas Leclerc
źródło
OP powiedział: „Więc tylko wtedy, gdy jeden i tylko jeden z warunków jest spełniony”. Twój fragment zwróci wartość true dla ciągu zawierającego wszystkie trzy słowa, przy czym OP chciałby, aby zwrócił fałsz.
Dane Brouwer
4

Można to zrobić za pomocą niektórych / wszystkich metod Array i RegEx.

Aby sprawdzić, czy WSZYSTKIE słowa z listy (tablicy) znajdują się w ciągu:

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

Aby sprawdzić, czy w ciągu znajdują się DOWOLNE słowa z listy (tablicy):

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
źródło
Łał. to odpowiadało na oba moje pytania. Dziękuję bardzo !!!!
BoundForGlory
2

Nie jest to najlepsza odpowiedź i nie najczystsza, ale myślę, że jest bardziej liberalna. Na przykład, jeśli chcesz używać tych samych filtrów do wszystkich kontroli. Właściwie .filter()działa z tablicą i zwraca przefiltrowaną tablicę (którą uważam za łatwiejszą w użyciu).

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
źródło
2

Oto kontrowersyjna opcja:

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

Umożliwiając wykonywanie takich czynności jak:

'Hi, hope you like this option'.toLowerCase().includesOneOf(["hello", "hi", "howdy"]) // True
James Broad
źródło
1

Inny!

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
źródło
-1

Rozszerzanie natywnego prototypu 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);
        }
    });
}

Umożliwiając wykonywanie takich czynności jak:

console.log('Hi, hope you like this option'.toLowerCase().contains(["hello", "hi", "howdy"])); // True
iProDev
źródło
-2

A co powiesz ['hello', 'hi', 'howdy'].includes(str)?

neatsu
źródło
1
Nie, to nie działa: ['hello', 'hi', 'howdy'].includes('hello, how are you ?')zwraca false, podczas gdy OP prosi o rozwiązanie, które zwraca true.
Basj,