简体   繁体   中英

Javascript check if items in an array are consecutive

Say I have an array which holds the values [1,2,3,6,7].

How can I check the array to see if it holds 3 consecutive numbers. For example, the array above holds [1,2,3] so this would return false in my function.

        var currentElement = null;
        var counter = 0;

        //check if the array contains 3 or more consecutive numbers:
        for (var i = 0; i < bookedAppArray.length; i++) {
            if ((bookedAppArray[i] != currentElement) && (bookedAppArray[i] === bookedAppArray[i - 1] + 1)) {

                if (counter > 2) {
                    return true;
                }

                currentElement = bookedAppArray[i];
                counter++;
            } else {
                counter = 1;
            }
        }

        if(counter > 2){
            return true;
        } else{
            return false;
        }

This solution

  • checks wheater the length of the array is greater than 2 ,
  • iterates over the array from position 2
  • gets the difference between position 2 and 1 before the index,
  • checks if the absolute difference is 1
  • checks the difference between position 1 before and at the index is equal the difference,
  • and if so, it returns false, because consecutive elements are found.
  • if not, increment index by 1

 function consecutive(array) { var i = 2, d; while (i < array.length) { d = array[i - 1] - array[i - 2]; if (Math.abs(d) === 1 && d === array[i] - array[i - 1]) { return false; } i++; } return true; } document.write(consecutive([1]) + '<br>'); // true document.write(consecutive([2, 4, 6]) + '<br>'); // true document.write(consecutive([9, 8, 7]) + '<br>'); // false document.write(consecutive([1, 2, 3, 6, 7]) + '<br>'); // false document.write(consecutive([1, 2, 3, 4, 5]) + '<br>'); // false

Thinking logically, this should be as easy as iterating over the array, and just checking the two indices previous to the current one.

Just adding 1 to the previous index, and 2 to the one before that one, and they should all be equal, something like this

function hasThree(arr) {
    var res = false;

    arr.forEach(function(item, index) {
        var l1 = arr[index - 1], // get previous
            l2 = arr[index - 2]; // get the one before the previous

        if ( l1 && l2 ) { // if two previous exist

            // add 1, and then 2, and see if all are equal

            if ( item === l1 + 1 && item === l2 + 2 ) res = true;
        }
    });

    return res;
}

FIDDLE

Interesting problem. Here is my attempt.

function cons(ar) {

    var cnt = 0;

    ar.forEach(function (i, idx) {
        if (idx > 0) {
            if (i == (ar[idx - 1] + 1)){
                cnt++;
            }
            else {
                if (cnt < 2)
                    cnt = 0;
            }
        }
    });

    return cnt < 2;
}

console.log('expected true', cons([1, 2, 5, 6, 9]));
console.log('expected false', cons([0, 2, 3, 4, 6, 9]));
console.log('expected false', cons([1, 2, 3, 4, 6, 9]));

Here is one. Just make sure to sort the array before doing it

function checkIfConsecutive(Arr) {
          let isCnsc = true;
          for (st in Arr ) {
               if ( Arr[parseInt(st)+1]-Arr[parseInt(st)] > 1 && !isNaN(Arr[parseInt(st)+1]-Arr[parseInt(st)] )) {
                    isCnsc = false;
               }
          }
           return isCnsc;
     }

I recently needed to do the same, and came up with this function, if someone sees it useful.

assert(!Array.prototype.isConsecutive, 'Array.isConsecutive rewriting conflict');
/**
 * Check if array consist of consecutive numbers
 * @param {number} [startFrom] If array should start from a specific number
 * @returns {Boolean} true if array consist of consecutive numbers
 */
Array.prototype.isConsecutive = /** @lends Array */ function (startFrom) {
  let curVal;
  if (startFrom !== undefined) curVal = startFrom - 1;
  // eslint-disable-next-line no-return-assign
  return this.every((n) => (
    !Number.isNaN(n)
    && (curVal = (curVal === undefined ? n : curVal + 1))
    && n === curVal)) || false;
};

It returns true if array is consecutive (more intuitive this way), you can add ! if you need a reverse. Here are some tests for it:

  it('Array.isConsecutive', () => {
    expect([1, 2, 3, 4].isConsecutive()).to.be.true;
    expect([1, 2, 3, 4].isConsecutive(1)).to.be.true;
    expect([5, 6, 7, 8].isConsecutive()).to.be.true;
    expect([6, 5, 7, 8, 9].isConsecutive()).to.be.false;
    expect([1, 2, 3, 4].isConsecutive(2)).to.be.false;
  });

PS. there are some ani-patterns (no assign and no prototype internal functions) in my example (I'm sure some dudes will dislike my answer), but I don't care, you can convert it into a function if you desire.

Try using Array.prototype.some() , Array.prototype.filter()

 var arr1 = [1, 2, 3, 9, 8, 7]; var arr2 = [1, 2, "a", 3]; var check = function(a) { // for each element in array `a` return !a.some(function(item, index) { // slice next three elements, including current element `item` from `a` array var next = a.slice(index, 3); console.log(next); // if next three items in array `a` are type `Number` // return `false`, else return `true` return next.filter(Number).length === 3 ? true : false }) }; // each item in `arr1` returns `false` , where item is followed // by two numbers // `arr2` returns `true` , where item is not followed by two numbers console.log(check([1,2,3]), check(arr1), check(arr2)) // `false`, `false`, `true`


Alternatively, using for loop , Array.prototype.every()

 var arr1 = [1, 2, 3, 9, 8, 7]; var arr2 = [1, 2, "a", 3]; var check = function(a) { var res; for (var i = 0; i < a.length; i++) { // if `a[i]` is followed by two numbers, return `false` if (a.slice(i, 3).every(function(n) { return typeof n === "number" })) { res = false; break; } // if `a[i]` is not followed by two numbers, return `true` else { res = true; break; } } return res } console.log(check([1,2,3]), check(arr1), check(arr2)) // `false`, `false` , `true`

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