Xác định xem chuỗi có ít nhất 2 phần tử giống nhau từ một mảng không


8

Tôi muốn xác định xem chuỗi có ít nhất 2 phần tử giống nhau từ mảng không

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

Tôi không chắc điều gì sẽ tốt hơn: regex hay hàm? Bất kỳ sẽ tốt thôi.

Tôi đã thử điều này:

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

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

Nhưng nó chỉ phát hiện nếu có ít nhất 1 phần tử từ mảng chứ không phải 2.


Sẽ chỉ có hai yếu tố trong mảng phù hợp, hoặc có thể có ba hoặc nhiều hơn?
Tim Biegeleisen

Cũng có thể là tốt hơn
Pleklo

Câu trả lời:


7

Bạn có thể sử dụng Array#someString#splitđể làm điều đó:

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"))

Làm thế nào nó hoạt động?

Hãy chia tay (ý tôi là split()lên)!

const check=(array,string)=>
  array.some(char=>
    (
      string.split(char)
      .length-1
    )>=2
  )
  • Đầu tiên, sử dụng Array#some, kiểm tra rằng ít nhất một phần tử của mảng sẽ vượt qua (nghĩa là ?hoặc! )
  • Chia chuỗi bằng char và đếm xem chúng ta có bao nhiêu phần
    • Nếu chúng ta có ncác bộ phận, điều đó có nghĩa là chúng ta có n-1những nơi charphù hợp. (ví dụ: |chia 2 chuỗi thành 3 phần a|b|c:)
  • Cuối cùng, kiểm tra xem chúng tôi có 2 dấu phân cách trở lên

Câu trả lời tốt nhất cho đến nay, dễ hiểu và khá ngắn!
Pleklo

không thể làm điều đó, vì bạn phải đợi một thời gian nhất định trước khi chấp nhận câu trả lời đúng :-)
Pleklo

Tôi đã cố gắng chấp nhận câu hỏi của bạn vài phút trước, khoảng 15-20 phút kể từ khi câu hỏi được hỏi tôi nghĩ
Pleklo

2

Một cách khác là sử dụng một mẫu với một nhóm bắt và một lớp nhân vật được tạo động cho [!?]và phản hồi \1lại những gì được chụp trong nhóm 1 để đảm bảo có 2 nhân vật giống nhau.

([!?]).*\1

Bản demo Regex

Ví dụ

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)));


Công trình này, trừ khi các mảng chứa một metacharater, ví dụ \, ], ^vv
FZS

1

Bạn có thể sử dụng chuỗi splitvà mảng lengthnhư:

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 : Sử dụng cho vòng lặp

for (let i=0;i<array.length;i++){
 var len = string6.split(array[i]).length;
 if (len>2)
  return true;
}
return false;

có ý nghĩa nhưng nếu mảng chứa nhiều phần tử thì sao? sẽ có rất nhiều mã lặp đi lặp lại
Pleklo

1

Bạn có thể làm theo một giải pháp rất đơn giản như dưới đây. Tách chuỗi bằng ký tự trong mảng. kiểm tra bên trái của hoạt động phân chia. Nếu độ dài tối thiểu là 2, thì trả về true, ngược lại là false.

Dưới đây là một mẫu 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);

Điều này hoạt động, nhưng OP đã đề cập rằng mảng không nhất thiết phải chứa chính xác 2 phần tử ...
FZ

Điều đó vẫn ổn, mã này chỉ để cung cấp cho bạn logic. Điều này có thể được sửa đổi bằng cách sử dụng một vòng lặp for. Bạn có thể chia sẻ những gì tất cả các nhân vật có mặt trong mảng của bạn?
Sagar Agrawal

Tôi biết cách thực hiện và chỉ cần thông báo cho bạn để giúp bạn trả lời tốt hơn
FZs

Tôi vừa sửa đổi mã của mình, vì vậy nếu mảng có nhiều hơn 2 phần tử / ký tự thì nó cũng sẽ hoạt động. Xem logic đã sửa đổi ở trên.
Sagar Agrawal

0

Tạo một chức năng có thể hữu ích cho nsố lần xuất hiện để tìm

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)

0

Sử dụng vòng lặp trên mảng và số lần xuất hiện sau đó kiểm tra xem sự xuất hiện có lớn hơn 1 không.

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


0

Đây là một cách tiếp cận thủ thuật regex. Chúng ta có thể thử xóa tất cả các ký tự khỏi đầu vào không phải là một phần của lớp ký tự cần tìm. Sau đó, khẳng định rằng có ít nhất hai ký tự riêng biệt còn lại trong đầu vào.

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

Logic ở đây khá đơn giản. Sử dụng đầu vào !hello?làm ví dụ, trước tiên chúng tôi xóa tất cả các ký tự không đánh dấu, để lại cho chúng tôi !?. Sau đó, chúng tôi sử dụng một biểu thức chính quy để khẳng định rằng có ít nhất hai ký tự riêng biệt còn lại. Điều này đúng với đầu vào này, vì vậy chúng tôi inMATCH .

Biên tập:

Để xây dựng luân phiên regex từ mảng đầu vào của bạn, hãy sử dụng join:

const array = ["!", "?"];
var regex = "[^" + array.join("") + "]+";

Vâng, câu trả lời của tim không chính xác, nó không nên khớp "! Xin chào?".
Pleklo

@Thefourthbird tôi khá mới với regex và có một câu hỏi, tôi có thể sử dụng mảng được xác định trong chuỗi regex không?
Pleklo

@Pleklo Tôi đã thực hiện một bản cập nhật cho bạn biết cách lấy từ mảng đầu vào của bạn sang mẫu regex.
Tim Biegeleisen

0

Có một giải pháp đơn giản hơn nhiều cho việc này:

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

Chúng ta có thể biến nó thành một hàm để kiểm tra:

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

Lưu ý: Mã của tôi đã thay đổi một vài lần và cuối cùng gần với câu trả lời được chấp nhận và tôi đã không nhận ra. Điều đó nói rằng, bạn không cần phải trừ đi bất cứ điều gì, vì vậy phần đó là không cần thiết.


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"))

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.