最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - Check if Javascript array values are in ascending order - Stack Overflow

programmeradmin2浏览0评论

Say I have an array of integers in Javascript, that I would like to check if all of its values are in ascending order. What i want is to save the array key in another array in case the algorithm finds a value that is lower (or equal) not only comparing the immediate previous one, but also comparing any value that is before it. What I did was this:

arr = [], nonvalid = [];

for (var j = 1; j < arr.length; j++){
    if ( arr[j+1] <= arr[j] ){
        nonvalid.push(j);
    }
}

Obviously the above algorightm checks only for values that are lower comparing the one before it.

An array might contain values like these:

arr = 1, 2, 3, 10, 5, 11, 12, 2, 4, 25

The non valid values are the bold ones. If I run the above loop, it won't "catch" the second last one (4), because it's higher than its closest left brother, but not that high than its all left brothers.

EDIT:

Tried the following solutions and none return all the nonvalid values for this array except mine . :(

They returned the last two values correctedly, but not the second one. I don't understand why though.

[24398, 24397, 25004, 25177, 26302, 28036, 29312, 29635, 29829, 30476, 32595, 33732, 34995, 36047, 36363, 37310, 38022, 38882, 40746, 41212, 42846, 43588, 44029, 44595, 44846, 45727, 46041, 47293, 48002, 48930, 49858, 51184, 51560, 53895, 54247, 54614, 55713, 56813, 57282, 57480, 57875, 58073, 58403, 60321, 61469, 62051, 62310, 62634, 63217, 64505, 65413, 65677, 65940, 66203, 66572, 67957, 68796, 68964, 69098, 69233, 69435, 69759, 71496, 72577, 72823, 73007, 73252, 73743, 73866, 76405, 77037, 77416, 77669, 79691, 80885, 81339, 81794, 82067, 82431, 83244, 84861, 86836, 88632, 89877, 90296, 91049, 91885, 92351, 92614, 93141, 93733, 93930, 94531, 95206, 95882, 96895, 97732, 97973, 99261, 99422, 99583, 100332, 100599, 101666, 102066, 102600, 103504, 104432, 105174, 107216, 109085, 110181, 110679, 111177, 111988, 112553, 113005, 113457, 600, 600]

Say I have an array of integers in Javascript, that I would like to check if all of its values are in ascending order. What i want is to save the array key in another array in case the algorithm finds a value that is lower (or equal) not only comparing the immediate previous one, but also comparing any value that is before it. What I did was this:

arr = [], nonvalid = [];

for (var j = 1; j < arr.length; j++){
    if ( arr[j+1] <= arr[j] ){
        nonvalid.push(j);
    }
}

Obviously the above algorightm checks only for values that are lower comparing the one before it.

An array might contain values like these:

arr = 1, 2, 3, 10, 5, 11, 12, 2, 4, 25

The non valid values are the bold ones. If I run the above loop, it won't "catch" the second last one (4), because it's higher than its closest left brother, but not that high than its all left brothers.

EDIT:

Tried the following solutions and none return all the nonvalid values for this array except mine . :(

They returned the last two values correctedly, but not the second one. I don't understand why though.

[24398, 24397, 25004, 25177, 26302, 28036, 29312, 29635, 29829, 30476, 32595, 33732, 34995, 36047, 36363, 37310, 38022, 38882, 40746, 41212, 42846, 43588, 44029, 44595, 44846, 45727, 46041, 47293, 48002, 48930, 49858, 51184, 51560, 53895, 54247, 54614, 55713, 56813, 57282, 57480, 57875, 58073, 58403, 60321, 61469, 62051, 62310, 62634, 63217, 64505, 65413, 65677, 65940, 66203, 66572, 67957, 68796, 68964, 69098, 69233, 69435, 69759, 71496, 72577, 72823, 73007, 73252, 73743, 73866, 76405, 77037, 77416, 77669, 79691, 80885, 81339, 81794, 82067, 82431, 83244, 84861, 86836, 88632, 89877, 90296, 91049, 91885, 92351, 92614, 93141, 93733, 93930, 94531, 95206, 95882, 96895, 97732, 97973, 99261, 99422, 99583, 100332, 100599, 101666, 102066, 102600, 103504, 104432, 105174, 107216, 109085, 110181, 110679, 111177, 111988, 112553, 113005, 113457, 600, 600]

Share Improve this question edited Apr 29, 2013 at 19:50 Ricardus asked Apr 29, 2013 at 19:09 RicardusRicardus 7392 gold badges8 silver badges15 bronze badges 2
  • 2 So could you keep track of a max value? – Chris Moutray Commented Apr 29, 2013 at 19:13
  • max value ah? Interesting! Let me try it. – Ricardus Commented Apr 29, 2013 at 19:19
Add a comment  | 

9 Answers 9

Reset to default 10

One other very nice functional way of doing this could be;

var isAscending = a => a.slice(1)
                        .map((e,i) => e > a[i])
                        .every(x => x);
                        
console.log(isAscending([1,2,3,4]));
console.log(isAscending([1,2,5,4]));

Nice code but there are redundancies in it. We can further simplify by consolidating .map() and .every() into one.

var isAscending = a => a.slice(1)
                        .every((e,i) => e > a[i]);
                        
console.log(isAscending([1,2,3,4]));
console.log(isAscending([1,2,5,4]));

Keep track of the largest value you have seen (see the fiddle):

function find_invalid_numbers(arr) {
    var nonvalid, i, max;

    nonvalid = [];

    if (arr.length !== 0) {
        max = arr[0];

        for (i = 1; i < arr.length; ++i) {
            if (arr[i] < max) {
                nonvalid.push(arr[i]);
            } else {
                max = arr[i];
            }
        }
    }

    return nonvalid;
}

When you find an element out of order, look at the next elements until they are no longer out of order relative to the element before the out of order one.

Add the out of order elements to the second array and continue from the new in order element.

var outs= [], L= A.length, i= 0, prev;
while(i<L){
    prev= A[i]; 
    while(A[++i]<prev) outs.push(i);
}
alert(outs)

Why not compare with the last known good number?

var arr = [1, 2, 3, 10, 5, 11, 12, 2, 4, 25],
    nonvalid = [],
    lastGoodValue = 0;

for (var j = 1; j < arr.length; j++) {
    if (j && arr[j] <= lastGoodValue) {
        //if not the first number and is less than the last good value
        nonvalid.push(arr[j]);
    } else {
        //if first number or a good value
        lastGoodValue = arr[j];
    }
}

console.log(arr, nonvalid)

DEMO

var arr = [24398, 24397, 25004, 25177, 26302, 28036, 29312, 29635, 29829, 30476, 32595, 33732, 34995, 36047, 36363, 37310, 38022, 38882, 40746, 41212, 42846, 43588, 44029, 44595, 44846, 45727, 46041, 47293, 48002, 48930, 49858, 51184, 51560, 53895, 54247, 54614, 55713, 56813, 57282, 57480, 57875, 58073, 58403, 60321, 61469, 62051, 62310, 62634, 63217, 64505, 65413, 65677, 65940, 66203, 66572, 67957, 68796, 68964, 69098, 69233, 69435, 69759, 71496, 72577, 72823, 73007, 73252, 73743, 73866, 76405, 77037, 77416, 77669, 79691, 80885, 81339, 81794, 82067, 82431, 83244, 84861, 86836, 88632, 89877, 90296, 91049, 91885, 92351, 92614, 93141, 93733, 93930, 94531, 95206, 95882, 96895, 97732, 97973, 99261, 99422, 99583, 100332, 100599, 101666, 102066, 102600, 103504, 104432, 105174, 107216, 109085, 110181, 110679, 111177, 111988, 112553, 113005, 113457, 600, 600],
    nonvalid = [],
    max = arr[0];

for(var j=0; j<arr.length; j++){
    var test= arr[j+1]<=max ? nonvalid.push(arr[j+1]) : max=arr[j];
}

alert(nonvalid); // 24397, 600, 600

a simple functional way to do it inline without loops or variables:

arr.filter(function(a,b,c){
  return  Math.max.apply(Math, c.slice(0,b)) > a ;
});

You can use map with this example:

const ascendingArray = [1,2,3,4,5,6,7];
const descendingArray = [1,2,3,7,5,6,4]

const isAscending = array => array.map((a, i) => a > array[i + 1]).indexOf(true) === -1

console.log(isAscending(descendingArray)); // should be false
console.log(isAscending(ascendingArray)); // should be true

Or, you can use filter with this example:

const ascendingArray = [1,2,3,4,5,6,7];
const descendingArray = [1,2,3,7,5,6,4]

const isAscending = array => array.filter((a, i) => a > array[i + 1]).length === 0;

console.log(isAscending(ascendingArray)); // should be true
console.log(isAscending(descendingArray)); // should be false

Copy the array first, remove any element that is not in order with array.splice(index, 1), and continue. That way, any element must by greater than the one right before it, but the one right before it will always be the max.

Answering my own question after taking your advices I tried the following algorightm. It seems to do its job but its a bit overkill.

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

for (var j = 1; j < arr.length; j++){

    if ( arr[j] > 0 && arr[i] > 0 && j != i ){

        if ( arr[j] <= arr[i] && j > i ){

            if ( jQuery.inArray(j, nonvalid) == - 1) nonvalid.push(j);
        }
    }
} }
发布评论

评论列表(0)

  1. 暂无评论