10

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;
        }
9
  • "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." Three consecutive of same number ? Commented Dec 13, 2015 at 22:30
  • You want to return FALSE if it does contain three consecutive numbers? That seems the wrong way around. Commented Dec 13, 2015 at 22:31
  • maybe 3 and 6 should return false? Commented Dec 13, 2015 at 22:32
  • 3
    May I ask, just to save myself the repeated typing, that people providing an answer explain their answer, that way people can understand what's going on, learn something from it and use that understanding to apply the demonstrated techniques in other situations? Unexplained black-box "do this" code doesn't help anyone outside of a very specific, and limited, situation. Commented Dec 13, 2015 at 22:45
  • 2
    @nicomp my attempt so far as been added. Commented Dec 13, 2015 at 22:56

6 Answers 6

7

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

Sign up to request clarification or add additional context in comments.

3 Comments

how come the last example is false? 1,2,3,4,5 shouldn't return true?
@AndreiPrãdan, it is consecutive and it should return false if so.
oh, I re-read the initial question... it's a little bit counterintuitive to call consecutive() and receive false when it's actually consecutive, but got it, thank you
1

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.

Comments

0

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

Comments

0

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

Comments

0

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

1 Comment

you might not even need IsNaN chek - i added it just in case but i am lazy to try it out now :)
-1

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`

1 Comment

What's it supposed to do? Have you even tested it? If yes, then can you explain why does it always return true, except for a completely empty array?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.