Check if value 3 in string array is the same

I want to check if my array has 3 same values ​​that are in a string.

for example

var arr = ["g", "z", "z", "z" ]; // Must be true

var arr = ["g", "z", "z", "v" ,"b", "b", "b"]; // Must be true

var arr = ["z", "g", "z", "z"]; // Must be false

      

JSFIDDLE

How can we verify this?

+3


source to share


8 answers


You can use Array#some

and test predecessors.

function check3(array) {
    return array.some(function (a, i, aa) {
        return i > 1 && a === aa[i - 2] && a === aa[i - 1];
    });
}

console.log(check3(["g", "z", "z", "z"]));                // true
console.log(check3(["g", "z", "z", "v" ,"b", "b", "b"])); // true
console.log(check3(["z", "g", "z", "z"]));                // false
console.log(check3(["z"]));                               // false
console.log(check3(["z", "z"]));                          // false
      

Run codeHide result




With a dynamic approach for any required length

function check(array, length) {
    var count = 0,
        value = array[0];

    return array.some(function (a) {
        if (value !== a) {
            count = 0;
            value = a;
        }
        return ++count === length;
    });
}

console.log('length: 3');
console.log(check(["g", "z", "z", "z"], 3));                // true
console.log(check(["g", "z", "z", "v" ,"b", "b", "b"], 3)); // true
console.log(check(["z", "g", "z", "z"], 3));                // false
console.log(check(["z"], 3));                               // false
console.log(check(["z", "z"], 3));                          // false

console.log('length: 4');
console.log(check(["g", "z", "z", "z", "z"], 4));           // true
console.log(check(["g", "z", "z", "b" ,"b", "b", "b"], 4)); // true
console.log(check(["z", "z", "z", "a"], 4));                // false
console.log(check(["z"], 4));                               // false
console.log(check(["z", "z"], 4));                          // false
      

.as-console-wrapper { max-height: 100% !important; top: 0; }
      

Run codeHide result


+3


source


Probably the most efficient approach would be to iterate through the input array only once and count sequences of consecutive equal elements. When a sufficiently long sequence is found, return true immediately. Return false when the end has been reached.



function hasConsecutive(arr, amount) {
    var last = null;
    var count = 0;
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] != last) {
            last = arr[i];
            count = 0;
        }
        count += 1;
        if (amount <= count) {
            return true;
        }
    }
    return false;
}

console.log(hasConsecutive(["g", "z", "z", "z"], 3))
console.log(hasConsecutive(["g", "z", "z", "z"], 4))
      

Run codeHide result


+4


source


Pass the array in this function,

check3inRow(dataArray)
{
        for(i=0 ; i < (dataArray.length-2) ; i++ )
        {
            if(dataArray[i] == dataArray[i+1] && dataArray[i+1] == dataArray[i+2])
            {
                return true;
            }
        }
    return false;
}

      

Doesn't check every element in the array like forEach, and also checks the array if it has more than two values, otherwise it will directly return false, ignore the last two elements since there is no need to compare those last two elements.

Less check, fewer loops, will lead to faster results.

+3


source


And slightly faster, with only 2 padding per element

function testFor3InARow(arr){
    var i = 0,len = arr.length-2;
    while(i < len){
       if(arr[i++] === arr[i] && arr[i] === arr[i+1]){
          return true;
       }
    }
    return false;
}

      

And by sacrificing one iteration step for a spurious result, it is possible to shorten the execution time with just one addition per element

function testFor3InARow(arr){
    var p = false,i = 0,len = arr.length -2;
    while(i <= len){
        if(p){
            if(p = (arr[i++] === arr[i])){ return true }
        }else{
            p = arr[i++] === arr[i];
        }
    }
    return false;
}

      

Update: After some testing, it looks like the first method is the fastest at 153μs ± 1μs per 1000 random arrays of 0-100 elements with 10% triple random arrangement. The second method obtained 193μs ± 0μs for the same data.

I checked some other answers and got the following results

Performance test. : 'Test for 3 in a row'
Use strict....... : true
Duplicates....... : 4
Cycles........... : 3078
Samples per cycle : 100
Browser.......... : Firefox 53.0b9 (32-bit)
OS............... : Windows 10 (32-bit)
---------------------------------------------
Test : 'By Blindman67 method A' Mean : 175µs ±2µs (*) 51635 samples
---------------------------------------------
Test : 'By Blindman67 method B' Mean : 212µs ±1µs (*) 50989 samples
---------------------------------------------
Test : 'By obyFS' Mean : 260µs ±0µs (*) 51211 samples
---------------------------------------------
Test : 'By Nina Scholz' Mean : 392µs ±2µs (*) 51384 samples
---------------------------------------------
Test : 'By fafl' Mean : 209µs ±1µs (*) 51433 samples
---------------------------------------------
Test : 'By Vivek Doshi' Mean : 188µs ±2µs (*) 51148 samples
-All ----------------------------------------
Mean : 0.239ms Totals time : 73680.010ms 307800 samples
(*) Error rate approximation does not represent the variance.

      

+2


source


The accepted answer is very naive, but as @fafl's answer my contribution will be a generic one that will return the n

number of identical consecutive elements. Here I am testing it with a 1,000,000 element array filled with random integers among 0..9 and checks for 6 consecutive elements, resolving less than 200ms.

function itemsInRow(a,n){
  return a.reduce(function(r,e,i){
                    r[0][i%n] = e;
                    r[0].every(x => x === r[0][0]) && r[1].push(r[0].slice());
                    return r;
                  }, [Array(n).fill(),[]])[1];
  
}

var arr = Array(1000000).fill().map(_ => ~~(Math.random()*10));
    res = [];
console.time("itemsInRow");
res = itemsInRow(arr,6);
console.timeEnd("itemsInRow");
console.log(JSON.stringify(res));
      

Run codeHide result


+2


source


Just try

function checkIfThreeConsecutive(arr) {
  var bool = false;

  arr.forEach(function(item, index, array) {
    if (index > 1 && (arr[index] == arr[index - 1]) && (arr[index] == arr[index - 2])) {
      bool = true;
    }
  });
  return bool;
}

console.log(checkIfThreeConsecutive(["g", "z", "z", "z"]));
      

Run codeHide result


+1


source


Use a simple loop

var arr = ["g", "z", "z", "v", "b", "b"];
var i, l = arr.length,
  status = false;
for (i = 0; i < l; i++) {
  if (arr[i] == arr[i + 1]) {
    if (arr[i + 1] == arr[i + 2])
      status = true;
  }
}
console.log(status)
      

Run codeHide result


+1


source


Simple with border checking

function checkIf3InRow(arr) {
    var arrLength = arr.length;
    if(arrLength < 3) {
        return false;
    }

    for(var i = 1; i < arrLength; i++) {
        if(i + 1 < arrLength && arr[i-1] == arr[i] && arr[i] == arr[i+ 1]) {
            return true;
        } 
    }
    return false;
}

      

+1


source







All Articles