Determinar se a string tem pelo menos 2 mesmos elementos de uma matriz

8

Eu quero determinar se a string tem pelo menos 2 mesmos elementos da matriz

const array = ["!", "?"];

const string1 = "!hello"; // should return false
const string2 = "!hello?"; // should return false
const string3 = "!hello!"; // should return true
const string4 = "hello ??"; // should return true
const string5 = "hello ?test? foo"; // should return true
const string6 = "hello ?test ?? foo"; // should return true

Não tenho certeza do que será melhor: uma expressão regular ou uma função? Qualquer um seria bom.

Eu tentei isso:

const array = ["!", "?"];
const string = "test!";

array.every(ar => !string.includes(ar));

Mas ele detecta apenas se houver pelo menos 1 elementos da matriz, não 2.

Pleklo
fonte
Haveria apenas dois elementos na matriz para corresponder ou também poderia haver três ou mais?
Tim Biegeleisen 01/10/19
Poderia ser mais bem
Pleklo

Respostas:

7

Você pode usar Array#somee String#splitfazer isso:

const check=(array,string)=>array.some(char=>(string.split(char).length-1)>=2)

const array = ["!", "?"];

console.log(check(array,"!hello"))
console.log(check(array,"!hello?"))
console.log(check(array,"!hello!"))
console.log(check(array,"hello ??"))
console.log(check(array,"hello ?test? foo"))
console.log(check(array, "hello ?test ?? foo"))

Como funciona?

Vamos nos separar (eu quero dizer split())!

const check=(array,string)=>
  array.some(char=>
    (
      string.split(char)
      .length-1
    )>=2
  )
  • Primeiro, use Array#some, que testa que pelo menos um elemento da matriz deve passar (ou seja, ?ou !)
  • Divida a sequência por chare conte quantas partes temos
    • Se temos npeças, significa que temos n-1lugares onde as charcorrespondências. (por exemplo, 2 |divide uma string em 3 partes a|b|c:)
  • Por fim, teste se temos 2 ou mais delimitadores
FZs
fonte
melhor resposta até agora, fácil de entender e muito curta!
Pleklo 01/10/19
Não poderia fazê-lo, desde que você tem que esperar certo tempo antes de aceitar resposta correta :-)
Pleklo
tentou aceitar suas mins questão par atrás, é cerca de 15-20 minutos do momento em que pergunta eu acho
Pleklo
2

Outra maneira é usar um padrão com um grupo de captura e um criado dinamicamente classe de personagem para [!?]e uma referência anterior \1ao que é capturado no grupo 1 para certificar-se há 2 do mesmo personagens presentes.

([!?]).*\1

Regex demo

Por exemplo

const array = ["!", "?"];
const regex = new RegExp("([" + array.join(("")) + "]).*\\1");
[
  "!hello",
  "!hello?",
  "!hello!",
  "hello ??",
  "hello ?test? foo",
  "hello ?test ?? foo"
].forEach(str => console.log(str + ": " + regex.test(str)));

O quarto pássaro
fonte
Isso funciona, a menos que a matriz conter um metacaractere, por exemplo, \, ], ^, etc.
FZS
1

Você pode usar string splite array lengthcomo:

const array = ["!", "?"];
const string6 = "hello ?test ?? foo"; 
var len1 = string6.split(array[0]).length;
var len2 = string6.split(array[1]).length;

if (len>2)||(len2>2)
 return true;

EDIT : Usando para loop

for (let i=0;i<array.length;i++){
 var len = string6.split(array[i]).length;
 if (len>2)
  return true;
}
return false;
apomene
fonte
faz sentido, mas e se a matriz contiver mais elementos? será um monte de código repetitivo
Pleklo 1/10/19
1

Você pode seguir uma solução muito simples como abaixo. Divida a sequência usando o caractere na matriz. verifique a esquerda da operação de divisão. Se o comprimento for mínimo 2, retorne true, caso contrário false.

Aqui está uma amostra do jsFiddle: https://jsfiddle.net/sagarag05/qk8f2Lz7/

const array = ["!", "?"];
var str = "How are you!! doing !today?";

function isFound(arr, str){
  var isPresent = false;
  for(var i=0; i < arr.length; i++){
      var res = str.split(arr[i]);
      if(res.length-1 >= 2){
          isPresent = true;
          break;
      }
  }
  return isPresent;
}
isFound(array, str);
Sagar Agrawal
fonte
Isso funciona, mas o OP mencionou que a matriz não necessariamente conter exatamente 2 elementos ...
FZS
Ainda está bem, esse código era apenas para lhe dar a lógica. Isso pode ser modificado usando um loop for. Você pode compartilhar o que todos os caracteres estão presentes em sua matriz?
Sagar Agrawal
Eu sei como fazê-lo, e apenas notificado você, para ajudá-lo a fazer o seu melhor resposta
FZS
Acabei de modificar meu código, portanto, se a matriz tiver mais de 2 elementos / caracteres, também funcionará. Veja a lógica modificada acima.
Sagar Agrawal
0

Crie uma função que possa ser útil para o nnúmero de ocorrências encontrar

const arrayData = ["!", "?"];
const strData = "test!";

function checkElements(arr, str, occNum) {
   var ctr = 0;
   arr.forEach(function (elem) { if(str.includes(elem)) ctr++});

   return ctr >= occNum
}

checkElements(arrayData, strData, 2)
Bilal Siddiqui
fonte
0

Use loop over array e conte a ocorrência e verifique se a ocorrência é maior que 1.

function has2(string1, array)
{
    for(let i=0;i<array.length;i++)
    {
        if (string1.split('').reduce(function(n, val) {
                return n + (val === array[i]);
            }, 0) > 1) 
        {
                return true;
        }
    }
    return false;
}

console.log(has2("!hello!", ["!", "?"])); // true
console.log(has2("!hello?", ["!", "?"])); // false

Mhd
fonte
0

Aqui está uma abordagem de truque de regex. Podemos tentar remover todos os caracteres da entrada que não fazem parte da classe de caracteres a serem encontrados. Em seguida, afirme que existem pelo menos dois caracteres distintos na entrada.

var input = "!hello?";
input = input.replace(/[^!?]+/g, "");
if (/(.).*(?!\1)./.test(input)) {
    console.log("MATCH");
}
else {
    console.log("NO MATCH");
}

A lógica aqui é bastante direta. Usando a entrada !hello?como exemplo, primeiro removemos todos os caracteres não marcadores, deixando-nos com !?. Em seguida, usamos um regex para afirmar que há pelo menos dois caracteres distintos. Isso é verdade para esta entrada, por isso imprimimos MATCH.

Editar:

Para criar a alternância regex a partir de sua matriz de entrada, use join:

const array = ["!", "?"];
var regex = "[^" + array.join("") + "]+";
Tim Biegeleisen
fonte
Sim, a resposta de tim não é correto, é deve não corresponder "Olá?".
Pleklo 01/10/19
@Thefourthbird sou muito novo para regex e tenho uma pergunta, posso usar a matriz definida dentro da string regex?
Pleklo 01/10/19
@Pleklo Fiz uma atualização que mostra como passar do seu array de entrada para um padrão regex.
Tim Biegeleisen 1/10/19
0

Existe uma solução muito mais simples para isso:

var a = ["!", "?"], s = "!hello!";
a.some(v=>s.split(v).length>2) // (returns true if multiples are found)

Podemos transformá-lo em uma função para testar:

const a = ["!", "?"];
function Test(s) { return a.some(v => s.split(v).length > 2) }
const string1 = "!hello"; // should return false
const string2 = "!hello?"; // should return false
const string3 = "!hello!"; // should return true
const string4 = "hello ??"; // should return true
const string5 = "hello ?test? foo"; // should return true
const string6 = "hello ?test ?? foo"; // should return true

console.log(Test(string1), Test(string2), Test(string3), Test(string4), 
  Test(string5), Test(string6));

> false false true true true true

Nota: Meu código mudou algumas vezes e, no final, estava próximo da resposta aceita, e eu não percebi. Dito isto, você não precisa subtrair nada, portanto essa parte é desnecessária.

James Wilkins
fonte
0

function checkDups(arr, str) {
    var ctr = [];


    for (var i = 0; i < arr.length; i++) {
        var pos = str.indexOf(arr[i]);
        var count = 0;
        ctr[i] = 0;


        while (pos > -1) {
            ++count;
            pos = str.indexOf(arr[i], ++pos);
        }



        if (count >= 2) {
            return true
        }

    }


    return false
}

console.log(checkDups(["!", "?"], "!hello"))
console.log(checkDups(["!", "?"], "!hello?"))
console.log(checkDups(["!", "?"], "!hello!"))
console.log(checkDups(["!", "?"], "hello ??"))
console.log(checkDups(["!", "?"], "hello ?test? foo"))
console.log(checkDups(["!", "?"], "hello ?test ?? foo"))

skmala
fonte