Javascript - How Do I Check if 3 Numbers Are Consecutive and Return Starting Points?
Asked Answered
T

5

7

If I have an array of [1, 2, 3, 5, 10, 9, 8, 9, 10, 11, 7] and wanted to find each case of 3 consecutive numbers (whether ascending or descending), how would I do that?

Second part would be then to alert an array with the index of each of these sequences.

For ex. the previous array would return [0,4,6,7].

So far I have this... which is a rough start

var arr = [1, 2, 3, 5, 10, 9, 8, 9, 10, 11, 7];
var results = [];

for (var i = 1; i < arr.length; i++) {
    if ((arr[i] - arr[i-1] != 1) && (arr[i] - arr[i+1] != 1)) {
        results.push(arr[i]);
    }

}
alert(results);

Thanks for the help!

Thanks for the math.abs pointer. This is what I ended up doing:

var array = [1, 2, 3, 5, 10, 9, 8, 9, 10, 11, 7];
var indexes = [];

for(var i=0; i < array.length; i++) {
    var diff = array[i+1] - array[i];
    if(Math.abs(diff)==1 && array[i+1]+diff == array[i+2]) {
        indexes.push(i);
    }
}
alert(indexes);
Trave answered 24/5, 2012 at 20:6 Comment(5)
But 0 isn't in your 'previous array'.Riproaring
I don't understand how [0,4,6,7] could be anything in your example...Ventura
i get 0 and 4, but 6,7? I think you are talking about the index of the starting number.Piscary
The trick is to notice that the OP has given two different example arrays. There's one element missing from the first one.Braze
The example results include an array defined as: indexOfMatch, item0, item1, item2Orozco
P
4

It'd be interesting to know the context of this task as well... Anyway, here's my solution:

var arr     = [1, 2, 3, 5, 10, 9, 8, 9, 10, 11, 7];
var results = [];
var limit   = arr.length - 1; 

var sequence = 0;
for (var i = 0; i < limit; ++i) {
  var diff = arr[i+1] - arr[i];
  if (sequence && sequence === diff) {
    results.push(i-1);
    continue;
  }
  sequence = (diff === 1 || diff === -1) // or ... Math.abs(diff) === 1
           ? diff
           : 0;
}
console.log(results);

The idea is simple: we don't need to compare two neighbors twice. ) It's enough to raise a kind of sequence flag if this comparation starts a sequence, and lower it if no sequence is there.

Pearse answered 24/5, 2012 at 20:36 Comment(3)
There is a bug with your solution. If the first two numbers in a new sequence are the same, e.g. var arr = [1, 1, 2, 3 ... then it thinks it sees a solution since sequence === diff. In this example -1 gets pushed into the results array, since it thinks there is a sequence beginning at 0. However, kudos for your solution's readability.Tepefy
You could change your if statement to if(sequence === diff && diff !== 0).Tepefy
Yep, somehow I failed to notice that two neighbors may be equal as well. Easily fixable, though; thanks for your observation! )Pearse
S
3

This is a very literal approach to your question - I have only checked forwards numbers, but adding reverse would be done almost in the same way

var arr = [1, 2, 3, 4, 10, 9, 8, 9, 10, 11, 7];
var results = [];

for (var i = 0; i < arr.length; i++) {

    // if next element is one more, and one after is two more
    if (arr[i+1] == arr[i]+1 && arr[i+2] == arr[i]+2){

        // store the index of matches
        results.push(i);

        // loop through next numbers, to prevent repeating longer sequences
        while(arr[i]+1 == arr[i+1])
            i++;
    }

}
console.log(results);
Situla answered 24/5, 2012 at 20:24 Comment(0)
E
2

You need to look closely at your expression in your if statement.

It currently says:

  • If the difference between the current element and previous element is not 1, and
  • If the difference between the current element and next element is not 1

then it's a result.

So, on the face of it, that's an incorrect logical statement to determine if the current element is in the middle of a consecutive set of three.

In addition, this doesn't account for an ascending or descending set of three either.

Try figuring out, in words, what the condition would look like and go from there.

Some things to consider

  • I suggest you start going through the list from i = 2
  • Research Math.abs
Elah answered 24/5, 2012 at 20:22 Comment(0)
S
1

This is I think a simpler way to do it. First check the average of the left and right number is equal to the middle, then check that the absolute value of either neighbor is one.

var arr = [1, 2, 3, 5, 10, 9, 8, 9, 10, 11, 7];
var indexes = [];

for(var i=1; i < arr.length; i++) {
    if((arr[i-1]+arr[i+1]) / 2 == arr[i] && Math.abs(arr[i]-arr[i-1]) == 1) {
        indexes.push(i-1);
    }
}
alert(indexes);
Situla answered 24/5, 2012 at 21:18 Comment(0)
O
0
var arr = [1, 2, 3, 5, 10, 9, 8, 9, 10, 11, 7];
var results = [];

for (var i = 0; i < arr.length - 2; i++) {
    if ((arr[i+1] - arr[i] === 1) && (arr[i+2] - arr[i+1] === 1)) {
        results.push({
            i:i,
            mode:'up',
            arr:[arr[i],arr[i+1],arr[i+2]
        });
    }
    if ((arr[i+1] - arr[i] === -1) && (arr[i+2] - arr[i+1] === -1)) {
        results.push({
            i:i,
            mode:'down',
            arr:[arr[i],arr[i+1],arr[i+2]
        });
    }

}
alert(results);
Orozco answered 24/5, 2012 at 20:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.