Check if an array is descending, ascending or not sorted?
Array.prototype.every
passes its predicate an index, which you can use to get an element’s predecessor:
function isAscending(arr) {
return arr.every(function (x, i) {
return i === 0 || x >= arr[i - 1];
});
}
Here, we’re checking that every item (x
) is greater than or equal to the item before it (arr[i - 1]
) or has no item before it (i === 0
).
Flip >=
to <=
for isDescending
.
This is a question that requires some sort of loop, with several if
statements because there are several cases you need to tackle:
- Array is empty or has only one element.
- All items in the array are equal
- Array is ascending - delta between 2 elements > 0, but some deltas may be 0
- Array is descending - delta between 2 elements < 0, but some deltas may be 0
- Not sorted - some deltas are > 0, and some are < 0
Depending on how the sorted is defined in the question, cases 1 & 2 might be regarded as unsorted as well.
function findSortOrder(arr) {
if(arr.length < 2) { // case 1
return 'not enough items'; // can also be 'unsorted'
}
var ascending = null;
var nextArr = arr.slice(1); // create an array that starts from the 2nd element of the original array
for(var i = 0; i < nextArr.length; i++) {
if (nextArr[i] === arr[i]) { // neutral - do nothing
} else if(ascending === null) { // define the the direction by the 1st delta encountered
ascending = nextArr[i] > arr[i];
} else if (ascending !== nextArr[i] > arr[i]) { // case 5
return 'unsorted';
}
}
if(ascending === null) { // case 2
return 'all items are equal'; // can also be 'unsorted'
}
return ascending ? 'ascending' : 'descending'; // cases 3 & 4
}
console.log(findSortOrder([1])); // case 1
console.log(findSortOrder([1, 1, 1, 1])); // case 2
console.log(findSortOrder([1, 1, 2, 3, 7, 7])); // case 3
console.log(findSortOrder([7, 2, 2, 1])); // case 4
console.log(findSortOrder([7, 2, 1, 3, 2, 1])); // case 5
"Check if an array is descending, ascending or not sorted using loops"
// define the array
var array = [1,2,3,7];
// keep track of things
var isDescending = true;
var isAscending = true;
// we're looking ahead; loop from the first element to one before the last element
for (var i=0, l=array.length-1; i<l; i++)
{
////////////////////////////////////////////////////////////
// log to the console to show what's happening for each loop iteration
// this is the ith iteration
console.log("loop iteration %s", i);
// breaking isDescending down:
// is this value greater than the next value?
console.log("A: (%s > %s) = %s", array[i], array[i+1], (array[i] > array[i+1]));
// have all values been descending so far?
console.log("B: isDescending: %s", isDescending);
// if this value is greater than the next and all values have been descending so far, isDescending remains true. Otherwise, it's set to false.
console.log("are A and B both true? %s", (isDescending && (array[i] > array[i+1])));
// add a line break for clarity
console.log("");
////////////////////////////////////////////////////////////
// true if this is greater than the next and all other so far have been true
isDescending = isDescending && (array[i] > array[i+1]);
// true if this is less than the next and all others so far have been true
isAscending = isAscending && (array[i] < array[i+1]);
}
if (isAscending)
{
console.log('Ascending');
}
else if (isDescending)
{
console.log('Descending');
}
else
{
console.log('Not Sorted');
}