简体   繁体   中英

Check if 3 in a row array value is same

I want to check if my array has 3 same values which are in a row.

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 check it?

Probably the most performant approach would be to iterate over the input-array only once and count streaks of consecutive equal elements. When a long enough sequence is found, return true immediately. When the end was reached, return false.

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

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

Will not check each element in array like forEach does and also validates the array if it has more than 2 values else it will directly return false , will ignore last two elements as there is no need to comparing those last two element.

Less checking , less looping , will get you faster result.

You could use Array#some and check the 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 

With a dynamic approach for any wanted 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; } 

And a little quicker with only 2 additions per item

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 sacrificing one iteration step for the false result can reduce execution time with only one addition per item

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 looks like the first method is the quickest at 153µs ±1µs per 1000 random arrays 0-100 items with 10% having a randomly located tripple. THe second method got 193µs ±0µs for the same data.

I have tested some of the 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.

The accepted answer is very naive but like @fafl 's answer my contribution would be a general one which would return n number of same consecutive items. Here i test it with a 1,000,000 item array filled with random integers among 0..9 and tests for 6 consecutive items, resolving in 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)); 

Simply 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"])); 

Use a simple for 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) 

Simple with bounds check

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM