JavaScript Object Sort method - javascript

In the compareNumeric fn I dont understand this concept with comparison.
To see more detailed: if (5 > 3) return 1; So what is this return 1 and return -1; how does it work, and how does it affect on sort method. Please , help me out!
function compareNumeric(a, b) {
if (a > b) return 1;
if (a < b) return -1;
}
var arr = [ 1, 2, 15, 14, 66, 434, 112, 3 ];
arr.sort(compareNumeric);
alert(arr); // sorted array

MDN's documentation for Array.prototype.sort will help. Basically, sort calls the callback repeatedly, with various combinations of two entries from the array. The callback's return value tells sort whether 1) a should be before of b in the result (by returning a negative value), or 2) a should be after b in the result (by returning a positive value), or 3) a and b are equivalent for sorting purposes so it doesn't matter (by returning 0).
Your example compareNumeric has a bug: It should return 0 if a is neither < nor > b, but instead it doesn't return anything, so calling it results in undefined. Instead:
function compareNumeric(a, b) {
if (a > b) { return 1; }
if (a < b) { return -1; }
return 0;
}
But, it has another problem: It never checks whether a and b are actually numeric. If the author is happy to assume they're numeric, it can be a simpler function:
function compareNumeric(a, b) {
return a - b;
}
If both a and b are numbers, then a - b will be negative if a is less than b and so should be before it in the result, positive if a is greater than b and so should be after it in the result, or 0 if a and b are equal.
Note that the number of times the callback gets called and in what order are not defined by the specification; all it says is that Array#sort will call the callback as necessary and use the resulting information.
Let's watch what arguments Array#sort gives with your example; again note that this will be implementation-dependent:
function compareNumeric(a, b) {
if (a > b) return 1;
if (a < b) return -1;
return 0;
}
var arr = [ 1, 2, 15, 14, 66, 434, 112, 3 ];
arr.sort(function(a, b) {
var result = compareNumeric(a, b);
console.log("a = " + a + ", b = " + b + "; returning " + result);
return result;
});
console.log(arr.join()); // sorted array
.as-console-wrapper {
max-height: 100% !important;
}

Related

Can't acces the global variable using RECURSION - JavaScript

Hello people I'm new to Javascipt.
Trying to print Fibonacci in Reverse by Recursion. example: RevFib(5) => 3,2,1,1,0
here is the code which works fine.
function fibo(n, a, b)
{
if (n > 0) {
// Function call
fibo(n - 1, b, a + b);
// Print the result
console.log(a);
}
}
fibo(5,0,1);
this works fine. but I don't want to output on console. instead I wanted to return a array contain all fibonacci numbers in reverse like [3,2,1,1,0].
I tried to implement it using defining a global array then try to passing that array in fibo() function. It doesn't work. don't know why.
here is the array code:
var arr = [];
function fibo(n, a, b, arr)
{
if (n > 0) {
// Function call
fibo(n - 1, b, a + b, arr);
// Print the result
console.log(a+' - '+arr);
arr.push(a);
}
}
fibo(5,0,1);
the output is error:
Uncaught TypeError: arr is undefined
as a newbie in JS. I can't get what went wrong. someone tell whats wrong here. Thanks
You're naming a function parameter called arr. Did you mean to do call fibo like so?:
function fibo(n, a, b, arr) {
if (n > 0) {
fibo(n - 1, b, a + b, arr);
console.log(a + ' - ' + arr);
arr.push(a);
}
}
let arr = [];
fibo(5, 0, 1, arr);
You also don't need arr to be a global variable if you're going to pass it as a function argument. Generally you should avoid globals (unless you have a special use case), because they make code harder to maintain. Passing the array to the fibo function is the right idea.
You could even have a wrapper function to make usage of return types.
function fiboRecurse(n, a, b, arr) {
if (n > 0) {
fiboRecurse(n - 1, b, a + b, arr);
console.log(a + ' - ' + arr);
arr.push(a);
}
}
function fibo(n) {
let arr = [];
fiboRecurse(n, 0, 1, arr);
return arr;
}
console.log(fibo(5));
You are naming a function parameter "arr" as well. The global variable will therefore not be accessible.
You were almost there with your own code. A few tweaks and it runs smoothly:
function fibo(n, a=0, b=1, arr=[]){
if (n > 0) {
fibo(n-1,b,a+b, arr);
arr.push(a);
}
return arr
}
const res=fibo(6);
console.log(res)
I used "optional arguments" in the function definition. If they are omitted at calling time they will have the values given in the function definition.

How to convert function parameters into an Array?

My function is taking in 2 integer parameters and returning the numbers between those two parameters. I cannot convert the numbers shown into an array.
As I'm supposed to buildArray function that takes two Numbers, and returns an Array filled with all numbers between the given number: buildArray(5, 10) should return [5, 6, 7, 8, 9, 10].
I have tried using split to convert the values into an array but I've failed many times.
My code prints each value separately whereas i need the values to be displayed in an array.
function buildArray(a, b) {
for (var i = 0; i <= b; i++) {
i = a;
console.log(a);
a = a + 1;
}
}
console.log(buildArray(5, 10));
Here is the simplest version using your original line of thoughts
Implementing a range function can be more complex than this, but since this works, I suggest it for now
function buildArray(a, b) {
var arr = [];
for (var i = a; i <= b; i++) {
arr.push(i);
}
return arr;
}
console.log(buildArray(5, 10));
You can construct a new array filled with zeros of the length you need and then use map() to set the values. I have updated to a generalized version for accept other types of ranges.
function buildArray(a, b)
{
let n = Math.abs(b - a);
return Array(n + 1).fill(0).map((x, idx) => a + ((b >= a) ? idx : -idx));
}
console.log(JSON.stringify(buildArray(5, 10)));
console.log(JSON.stringify(buildArray(12, 3)));
console.log(JSON.stringify(buildArray(1, -2)));
console.log(JSON.stringify(buildArray(-1, -1)));
Try the following (using Array.from):
function buildArray(min, max) {
return Array.from({ length: max - min + 1 }, (_, i) => min + i);
}
console.log(buildArray(5, 10));

Inversing a boolean based on a variable

Say for example I have a sorting function but I want to reverse it based on another variable.
What I know
if else
ternary ?
I was wondering if there was some kind of cool trick like (true && "return this") or !!(+num % 2) kind of stuff.
Example:
var array = [3,5,2,1,7,8,10];
var reverse = true;
array.sort( function(a,b) {
return a < b // somehow use reverse to sort it reverse order
});
Addendum
While David's answer was the one I was looking for in response to my question. This is what I think would be appropriate if I was looking to conditionally sort: Short circuiting.
var array = [3,5,2,1,7,8,10];
var reverse = true;
function number_sort(a,b) {
return a > b ;
}
(array.sort(number_sort) && reverse && array.reverse());
console.log(array);
reverse = false;
(array.sort(number_sort) && reverse && array.reverse());
console.log(array);
Seeing as you're just returning a boolean from your sort, you could return the boolean value of whether or not your boolean matches your reverse variable:
array.sort( function(a,b) {
return a < b == reverse
});
I would conditionally choose the sort function:
array.sort(reverse
? (a, b) => a - b
: (a, b) => b - a
);
Advantage is that condition is evaluated only once instead of for every item.
Otherwise, quite obvious:
array.sort(...);
if (reverse) {
array.reverse();
}
You could use a variable asc, which could have the value true for ascending sorting or false for descending sorting. Then use the value of asc as factor, if given or use -1 for descending sorting.
The factor -1 reverses the sort order as needed for the sort function.
var array = [3, 5, 2, 1, 7, 8, 10],
asc = false;
array.sort(function(a, b) { return (asc || -1) * (a - b); });
console.log(array);
asc = true;
array.sort(function(a, b) { return (asc || -1) * (a - b); });
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Version with a closure over the sort order
var sortFn = function (asc) {
return function(a, b) {
return (asc || -1) * (a - b);
};
},
array = [3, 5, 2, 1, 7, 8, 10];
array.sort(sortFn(false)); // desc
console.log(array);
array.sort(sortFn(true)); // asc
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can also use a ternary operator:
var array = [3,5,2,1,7,8,10];
var reverse = true;
array.sort( function(a,b) {
return reverse ? (a > b) : (a < b)
});

.sort() method not working

function isSorted(set) {
if(set == set.sort()) {
return true;
} else {
return false;
}
}
This function is supposed to check if an array is sorted properly, but no matter what, it still returns true.
From MDN:
The sort() method sorts the elements of an array in place and returns the array.
After set.sort() is invoked, set itself has been sorted, so set will always equal set.sort().
Reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
As pointed out in the comments, == compares by reference and hence still refers to the same array. Thereby the condition is always true
Use the below method to ensure if the array is sorted or not. Found the method form here
/*
* check the array is sorted
* return: if positive (ascending) -> 1
* if negative (descending) -> -1
* not sorted -> 0
*/
Array.prototype.isSorted = function() {
return (function(direction) {
return this.reduce(function(prev, next, i, arr) {
if (direction === undefined)
return (direction = prev <= next ? 1 : -1) || true;
else
return (direction + 1 ?
(arr[i-1] <= next) :
(arr[i-1] > next));
}) ? Number(direction) : false;
}).call(this);
}
var arr = [3,2,1,0];
arr.isSorted();
Or you can create a similar function like this using the above code
/*
* check the array is sorted
* return: if positive (ascending) -> 1
* if negative (descending) -> -1
* not sorted -> 0
*/
function isSorted(myArray) {
return (function(direction) {
return myArray.reduce(function(prev, next, i, arr) {
if (direction === undefined)
return (direction = prev <= next ? 1 : -1) || true;
else
return (direction + 1 ?
(arr[i-1] <= next) :
(arr[i-1] > next));
}) ? Number(direction) : false;
}).call(myArray);
}
var arr = [3,2,1,0];
isSorted(arr);
I suggest to use another way to check, if an array is sorted. You could use a compareFunction as described by Array#sort and use it as check for test as sorted with Array#every
For example, if you have numbers and a compareFunction like
var greaterOrEqual = function (a, b ) { return a - b; }
you could use the function to sort an array with number like
array.sort(greaterOrEqual);
and you could use the following pattern for checking every element
var isSorted = function (compareFunction) {
return function (a, i, aa) {
return !(compareFunction(aa[i - 1], a) > 0);
};
};
and then use it with an array, like
var isSorted = array.every(isSorted(greaterOrEqual));
A working example
var greaterOrEqual = function (a, b ) { return a - b; },
isSorted = function (compareFunction) {
return function (a, i, aa) {
return !(compareFunction(aa[i - 1], a) > 0);
};
};
console.log([42].every(isSorted(greaterOrEqual))); // true
console.log([42, 42].every(isSorted(greaterOrEqual))); // true
console.log([1, 2, 3, 4, 5].every(isSorted(greaterOrEqual))); // true
console.log([1, 2, 5, 4, 3].every(isSorted(greaterOrEqual))); // false
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to sort an array of integers correctly

Trying to get the highest and lowest value from an array that I know will contain only integers seems to be harder than I thought.
var numArray = [140000, 104, 99];
numArray = numArray.sort();
console.log(numArray)
I'd expect this to show 99, 104, 140000. Instead it shows 104, 140000, 99. So it seems the sort is handling the values as strings.
Is there a way to get the sort function to actually sort on integer value?
By default, the sort method sorts elements alphabetically. To sort numerically just add a new method which handles numeric sorts (sortNumber, shown below) -
var numArray = [140000, 104, 99];
numArray.sort(function(a, b) {
return a - b;
});
console.log(numArray);
Documentation:
Mozilla Array.prototype.sort() recommends this compare function for arrays that don't contain Infinity or NaN. (Because Infinity - Infinity is NaN, not 0).
Also examples of sorting objects by key.
Just building on all of the above answers, they can also be done in one line like this:
var numArray = [140000, 104, 99];
numArray = numArray.sort(function (a, b) { return a - b; });
//outputs: 99, 104, 140000
I am surprised why everyone recommends to pass a comparator function to sort(), that makes sorting really slow!
To sort numbers, just create any TypedArray:
var numArray = new Float64Array([140000, 104, 99]);
numArray = numArray.sort();
console.log(numArray)
array.sort does a lexicographic sort by default, for a numeric sort, provide your own function. Here's a simple example:
function compareNumbers(a, b)
{
return a - b;
}
numArray.sort(compareNumbers);
Also note that sort works "in place", there's no need for the assignment.
This answer is equivalent to some of the existing answers, but ECMAScript 6 arrow functions provide a much more compact syntax that allows us to define an inline sort function without sacrificing readability:
numArray = numArray.sort((a, b) => a - b);
It is supported in most browsers today.
The reason why the sort function behaves so weird
From the documentation:
[...] the array is sorted according to each character's Unicode code point
value, according to the string conversion of each element.
If you print the unicode point values of the array then it will get clear.
console.log("140000".charCodeAt(0));
console.log("104".charCodeAt(0));
console.log("99".charCodeAt(0));
//Note that we only look at the first index of the number "charCodeAt( 0 )"
This returns: "49, 49, 57".
49 (unicode value of first number at 140000)
49 (unicode value of first number at 104)
57 (unicode value of first number at 99)
Now, because 140000 and 104 returned the same values (49) it cuts the first index and checks again:
console.log("40000".charCodeAt(0));
console.log("04".charCodeAt(0));
//Note that we only look at the first index of the number "charCodeAt( 0 )"
52 (unicode value of first number at 40000)
40 (unicode value of first number at 04)
If we sort this, then we will get:
40 (unicode value of first number at 04)
52 (unicode value of first number at 40000)
so 104 comes before 140000.
So the final result will be:
var numArray = [140000, 104, 99];
numArray = numArray.sort();
console.log(numArray)
104, 140000, 99
Conclusion:
sort() does sorting by only looking at the first index of the numbers. sort() does not care if a whole number is bigger than another, it compares the value of the unicode of the digits, and if there are two equal unicode values, then it checks if there is a next digit and compares it as well.
To sort correctly, you have to pass a compare function to sort() like explained here.
just do .sort((a, b) => a - b) instead of .sort() itself. In addition to that the array is sorted in place. So return value does not matter.
var numArray = [140000, 104, 99];
numArray.sort((a, b) => a - b);
console.log(numArray)
Ascending
arr.sort((a, b) => a - b);
Descending
arr.sort((a, b) => b - a);
Just for fun:
Descending = Ascending + Reverse
arr.sort((a, b) => a - b).reverse();
I agree with aks, however instead of using
return a - b;
You should use
return a > b ? 1 : a < b ? -1 : 0;
The question has already been answered, the shortest way is to use sort() method. But if you're searching for more ways to sort your array of numbers, and you also love cycles, check the following
Insertion sort
Ascending:
var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length; i++) {
var target = numArray[i];
for (var j = i - 1; j >= 0 && (numArray[j] > target); j--) {
numArray[j+1] = numArray[j];
}
numArray[j+1] = target
}
console.log(numArray);
Descending:
var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length; i++) {
var target = numArray[i];
for (var j = i - 1; j >= 0 && (numArray[j] < target); j--) {
numArray[j+1] = numArray[j];
}
numArray[j+1] = target
}
console.log(numArray);
Selection sort:
Ascending:
var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length - 1; i++) {
var min = i;
for (var j = i + 1; j < numArray.length; j++) {
if (numArray[j] < numArray[min]) {
min = j;
}
}
if (min != i) {
var target = numArray[i];
numArray[i] = numArray[min];
numArray[min] = target;
}
}
console.log(numArray);
Descending:
var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length - 1; i++) {
var min = i;
for (var j = i + 1; j < numArray.length; j++) {
if (numArray[j] > numArray[min]) {
min = j;
}
}
if (min != i) {
var target = numArray[i];
numArray[i] = numArray[min];
numArray[min] = target;
}
}
console.log(numArray);
Have fun
In JavaScript the sort() method's default behaviour is to sort values in an array alphabetically.
To sort by number you have to define a numeric sort function (which is very easy):
...
function sortNumber(a, b)
{
return a - b;
}
numArray = numArray.sort(sortNumber);
Array.sort uses alphabetic sorting by default instead of numeric .
To support numbers, add like following
var numArray = [140000, 104, 99];
numArray.sort((a, b) => a - b); // <-- Ascending
numArray.sort((a, b) => b - a); // <-- Descending
console.log(numArray);
OUTPUT :
Array.prototype.sort() is the go to method for sorting arrays, but there are a couple of issues we need to be aware of.
The sorting order is by default lexicographic and not numeric regardless of the types of values in the array. Even if the array is all numbers, all values will be converted to string and sorted lexicographically.
So should we need to customize the sort() and reverse() method like below.
Referred URL
For sorting numbers inside the array
numArray.sort(function(a, b)
{
return a - b;
});
For reversing numbers inside the array
numArray.sort(function(a, b)
{
return b - a;
});
Referred URL
to handle undefined, null, and NaN: Null behaves like 0, NaN and undefined goes to end.
array = [3, 5, -1, 1, NaN, 6, undefined, 2, null]
array.sort((a,b) => isNaN(a) || a-b)
// [-1, null, 1, 2, 3, 5, 6, NaN, undefined]
The function 'numerically' below serves the purpose of sorting array of numbers numerically in many cases when provided as a callback function:
function numerically(a, b){
return a-b;
}
array.sort(numerically);
But in some rare instances, where array contains very large and negative numbers, an overflow error can occur as the result of a-b gets smaller than the smallest number that JavaScript can cope with.
So a better way of writing numerically function is as follows:
function numerically(a, b){
if(a < b){
return -1;
} else if(a > b){
return 1;
} else {
return 0;
}
}
While not required in JavaScript, if you would like the sort() compareFunction to strictly return -1, 0, or 1 (similar to how the spaceship operator works in PHP), then you can use Math.sign().
The compareFunction below strictly returns -1, 0, or 1:
numArray.sort((a, b) => Math.sign(a - b));
Note: Math.sign() is not supported in Internet Explorer.
The accepted answer and equivalents like numArray.sort((a,b) => a - b) are great when the array contains only numbers without infinities or NaN. They can be extended to handle infinities and NaN like so:
numArray.sort((a,b) => (+a || 0) - (+b || 0) || 0);
This sorts NaN (or any non-number, like 'foo' or {}) as if it were 0. The final || 0 is needed to handle the case where a and b are equal infinities.
For a normal array of elements values only:
function sortArrayOfElements(arrayToSort) {
function compareElements(a, b) {
if (a < b)
return -1;
if (a > b)
return 1;
return 0;
}
return arrayToSort.sort(compareElements);
}
e.g. 1:
var array1 = [1,2,545,676,64,2,24]
**output : [1, 2, 2, 24, 64, 545, 676]**
var array2 = ["v","a",545,676,64,2,"24"]
**output: ["a", "v", 2, "24", 64, 545, 676]**
For an array of objects:
function sortArrayOfObjects(arrayToSort, key) {
function compareObjects(a, b) {
if (a[key] < b[key])
return -1;
if (a[key] > b[key])
return 1;
return 0;
}
return arrayToSort.sort(compareObjects);
}
e.g. 1: var array1= [{"name": "User4", "value": 4},{"name": "User3", "value": 3},{"name": "User2", "value": 2}]
**output : [{"name": "User2", "value": 2},{"name": "User3", "value": 3},{"name": "User4", "value": 4}]**
Update! Scroll to bottom of answer for smartSort prop additive that gives even more fun!Sorts arrays of anything!
My personal favorite form of this function allows for a param for Ascending, or Descending:
function intArraySort(c, a) {
function d(a, b) { return b - a; }
"string" == typeof a && a.toLowerCase();
switch (a) {
default: return c.sort(function(a, b) { return a - b; });
case 1:
case "d":
case "dc":
case "desc":
return c.sort(d)
}
};
Usage as simple as:
var ara = function getArray() {
var a = Math.floor(Math.random()*50)+1, b = [];
for (i=0;i<=a;i++) b.push(Math.floor(Math.random()*50)+1);
return b;
}();
// Ascending
intArraySort(ara);
console.log(ara);
// Descending
intArraySort(ara, 1);
console.log(ara);
// Ascending
intArraySort(ara, 'a');
console.log(ara);
// Descending
intArraySort(ara, 'dc');
console.log(ara);
// Ascending
intArraySort(ara, 'asc');
console.log(ara);
jsFiddle
Or Code Snippet Example Here!
function intArraySort(c, a) {
function d(a, b) { return b - a }
"string" == typeof a && a.toLowerCase();
switch (a) {
default: return c.sort(function(a, b) { return a - b });
case 1:
case "d":
case "dc":
case "desc":
return c.sort(d)
}
};
function tableExample() {
var d = function() {
var a = Math.floor(50 * Math.random()) + 1,
b = [];
for (i = 0; i <= a; i++) b.push(Math.floor(50 * Math.random()) + 1);
return b
},
a = function(a) {
var b = $("<tr/>"),
c = $("<th/>").prependTo(b);
$("<td/>", {
text: intArraySort(d(), a).join(", ")
}).appendTo(b);
switch (a) {
case 1:
case "d":
case "dc":
case "desc":
c.addClass("desc").text("Descending");
break;
default:
c.addClass("asc").text("Ascending")
}
return b
};
return $("tbody").empty().append(a(), a(1), a(), a(1), a(), a(1), a(), a(1), a(), a(1), a(), a(1))
};
tableExample();
table { border-collapse: collapse; }
th, td { border: 1px solid; padding: .25em .5em; vertical-align: top; }
.asc { color: red; }
.desc { color: blue }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table><tbody></tbody></table>
.smartSort('asc' | 'desc')
Now have even more fun with a sorting method that sorts an array full of multiple items! Doesn't currently cover "associative" (aka, string keys), but it does cover about every type of value! Not only will it sort the multiple values asc or desc accordingly, but it will also maintain constant "position" of "groups" of values. In other words; ints are always first, then come strings, then arrays (yes, i'm making this multidimensional!), then Objects (unfiltered, element, date), & finally undefineds and nulls!
"Why?" you ask. Why not!
Now comes in 2 flavors! The first of which requires newer browsers as it uses Object.defineProperty to add the method to the Array.protoype Object. This allows for ease of natural use, such as: myArray.smartSort('a'). If you need to implement for older browsers, or you simply don't like modifying native Objects, scroll down to Method Only version.
/* begin */
/* KEY NOTE! Requires EcmaScript 5.1 (not compatible with older browsers) */
;;(function(){if(Object.defineProperty&&!Array.prototype.smartSort){var h=function(a,b){if(null==a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return a-b;if(/^stringstring$/ig.test(e))return a>b;if(/(string|number){2}/ig.test(e))return/string/i.test(c)?1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.smartSort("a");b instanceof Array&&b.smartSort("a");if(a instanceof Date&&b instanceof Date)return a-b;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=e.concat(g).smartSort("a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=[a[c],b[c]].smartSort("a"),a[c]==d[0]?-1:1;var f=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("a");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=[a.id,b.id].smartSort("a"),a.id==e[0]?1:-1;e=[a.tagName, b.tagName].smartSort("a");return a.tagName==e[0]?1:-1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);e.concat(g).smartSort("a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&&b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=[a[d].id,b[f].id].smartSort("a"),a[d].id==c[0]?-1:1;c=[a[d].tagName,b[f].tagName].smartSort("d"); return a[d].tagName==c[0]?1:-1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=[a[d],b[f]].smartSort("a"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1;if(b.hasOwnProperty(f)&&b[f]instanceof Element||!a.hasOwnProperty(d))return-1;if(!b.hasOwnProperty(d))return 1}c=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("d");return a[Object.keys(a)[0]]==c[0]?-1:1}g=[a,b].sort();return g[0]>g[1]},k=function(a,b){if(null== a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return b-a;if(/^stringstring$/ig.test(e))return b>a;if(/(string|number){2}/ig.test(e))return/string/i.test(c)?1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.smartSort("d");b instanceof Array&&b.smartSort("d");if(a instanceof Date&&b instanceof Date)return b-a;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=e.concat(g).smartSort("a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=[a[c],b[c]].smartSort("d"),a[c]==d[0]?-1:1;var f=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("d");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=[a.id,b.id].smartSort("d"),a.id==e[0]?-1:1;e=[a.tagName,b.tagName].smartSort("d");return a.tagName==e[0]?-1:1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);e.concat(g).smartSort("a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&&b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=[a[d].id,b[f].id].smartSort("d"),a[d].id==c[0]?-1:1;c=[a[d].tagName,b[f].tagName].smartSort("d");return a[d].tagName==c[0]?-1:1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=[a[d],b[f]].smartSort("d"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1;if(b.hasOwnProperty(f)&&b[f]instanceof Element)return-1;if(!a.hasOwnProperty(d))return 1;if(!b.hasOwnProperty(d))return-1}c=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("d");return a[Object.keys(a)[0]]==c[0]?-1:1}g=[a,b].sort();return g[0]<g[1]};Object.defineProperty(Array.prototype,"smartSort",{value:function(){return arguments&& (!arguments.length||1==arguments.length&&/^a([sc]{2})?$|^d([esc]{3})?$/i.test(arguments[0]))?this.sort(!arguments.length||/^a([sc]{2})?$/i.test(arguments[0])?h:k):this.sort()}})}})();
/* end */
jsFiddle Array.prototype.smartSort('asc|desc')
Use is simple! First make some crazy array like:
window.z = [ 'one', undefined, $('<span />'), 'two', null, 2, $('<div />', { id: 'Thing' }), $('<div />'), 4, $('<header />') ];
z.push(new Date('1/01/2011'));
z.push('three');
z.push(undefined);
z.push([ 'one', 'three', 'four' ]);
z.push([ 'one', 'three', 'five' ]);
z.push({ a: 'a', b: 'b' });
z.push({ name: 'bob', value: 'bill' });
z.push(new Date());
z.push({ john: 'jill', jack: 'june' });
z.push([ 'abc', 'def', [ 'abc', 'def', 'cba' ], [ 'cba', 'def', 'bca' ], 'cba' ]);
z.push([ 'cba', 'def', 'bca' ]);
z.push({ a: 'a', b: 'b', c: 'c' });
z.push({ a: 'a', b: 'b', c: 'd' });
Then simply sort it!
z.smartSort('asc'); // Ascending
z.smartSort('desc'); // Descending
Method Only
Same as the preceding, except as just a simple method!
/* begin */
/* KEY NOTE! Method `smartSort` is appended to native `window` for global use. If you'd prefer a more local scope, simple change `window.smartSort` to `var smartSort` and place inside your class/method */
window.smartSort=function(){if(arguments){var a,b,c;for(c in arguments)arguments[c]instanceof Array&&(a=arguments[c],void 0==b&&(b="a")),"string"==typeof arguments[c]&&(b=/^a([sc]{2})?$/i.test(arguments[c])?"a":"d");if(a instanceof Array)return a.sort("a"==b?smartSort.asc:smartSort.desc)}return this.sort()};smartSort.asc=function(a,b){if(null==a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return a-b;if(/^stringstring$/ig.test(e))return a> b;if(/(string|number){2}/ig.test(e))return/string/i.test(c)?1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.sort(smartSort.asc);b instanceof Array&&b.sort(smartSort.asc);if(a instanceof Date&&b instanceof Date)return a-b;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=smartSort(e.concat(g),"a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=smartSort([a[c], b[c]],"a"),a[c]==d[0]?-1:1;var f=smartSort([a[Object.keys(a)[0]],b[Object.keys(b)[0]]],"a");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=smartSort([a.id,b.id],"a"),a.id==e[0]?1:-1;e=smartSort([a.tagName,b.tagName],"a");return a.tagName==e[0]?1:-1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);smartSort(e.concat(g), "a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&&b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=smartSort([a[d].id,b[f].id],"a"),a[d].id==c[0]?-1:1;c=smartSort([a[d].tagName,b[f].tagName],"a");return a[d].tagName==c[0]?-1:1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=smartSort([a[d],b[f]],"a"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1; if(b.hasOwnProperty(f)&&b[f]instanceof Element||!a.hasOwnProperty(d))return-1;if(!b.hasOwnProperty(d))return 1}c=smartSort([a[Object.keys(a)[0]],b[Object.keys(b)[0]]],"a");return a[Object.keys(a)[0]]==c[0]?1:-1}g=[a,b].sort();return g[0]>g[1]};smartSort.desc=function(a,b){if(null==a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return b-a;if(/^stringstring$/ig.test(e))return b>a;if(/(string|number){2}/ig.test(e))return/string/i.test(c)? 1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.sort(smartSort.desc);b instanceof Array&&b.sort(smartSort.desc);if(a instanceof Date&&b instanceof Date)return b-a;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=smartSort(e.concat(g),"a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=smartSort([a[c],b[c]],"d"),a[c]==d[0]?-1:1;var f=smartSort([a[Object.keys(a)[0]], b[Object.keys(b)[0]]],"d");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=smartSort([a.id,b.id],"d"),a.id==e[0]?-1:1;e=smartSort([a.tagName,b.tagName],"d");return a.tagName==e[0]?-1:1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);smartSort(e.concat(g),"a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&& b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=smartSort([a[d].id,b[f].id],"d"),a[d].id==c[0]?-1:1;c=smartSort([a[d].tagName,b[f].tagName],"d");return a[d].tagName==c[0]?-1:1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=smartSort([a[d],b[f]],"d"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1;if(b.hasOwnProperty(f)&&b[f]instanceof Element)return-1; if(!a.hasOwnProperty(d))return 1;if(!b.hasOwnProperty(d))return-1}c=smartSort([a[Object.keys(a)[0]],b[Object.keys(b)[0]]],"d");return a[Object.keys(a)[0]]==c[0]?-1:1}g=[a,b].sort();return g[0]<g[1]}
/* end */
Use:
z = smartSort(z, 'asc'); // Ascending
z = smartSort(z, 'desc'); // Descending
jsFiddle Method smartSort(Array, "asc|desc")
Try this code:
HTML:
<div id="demo"></div>
JavaScript code:
<script>
(function(){
var points = [40, 100, 1, 5, 25, 10];
document.getElementById("demo").innerHTML = points;
points.sort(function(a, b){return a-b});
document.getElementById("demo").innerHTML = points;
})();
</script>
Try this code as below
var a = [5, 17, 29, 48, 64, 21];
function sortA(arr) {
return arr.sort(function(a, b) {
return a - b;
})
;}
alert(sortA(a));
TypeScript variant
const compareNumbers = (a: number, b: number): number => a - b
myArray.sort(compareNumbers)
In order to create this kind of sort, you have to pass a function that will check which comes first.
define inside the function which value do you wanna check: a.id - a.id
const myJson = [
{ id: 1, name: 'one'},
{ id: 4, name: 'four'},
{ id: 2, name: 'two'},
{ id: 3, name: 'three'}
];
// provide the sort method to check
const myNewSort = myJson.sort(function(a, b) {
return a.id - b.id;
});
console.log('my new sort',myNewSort)
You can sort number array simply by
const num=[13,17,14,19,16];
let temp;
for(let i=0;i<num.length;i++){
for(let j=i+1;j<num.length;j++){
if(num[i]>num[j]){
temp=num[i]
num[i]=num[j]
num[j]=temp
}
}
}
console.log(num);
let grade =[80,100,50,90,40];
grade.sort((x,y)=> x-y);
grade.forEach(element=>console.log(element));
Sort integers > 0, think outside the box:
function sortArray(arr) {
return new Promise((resolve) => {
const result = []
arr.forEach((item) => {
setTimeout(() => {
result.push(item)
if (result.length === arr.length) resolve(result)
}, item)
})
})
}
sortArray([4, 2, 42, 128, 56, 2]).then((result) => {
document.write(JSON.stringify(result))
})
Note that this should not be used productively, .sort() is better suited for this, check the other answers
sort_mixed
Object.defineProperty(Array.prototype,"sort_mixed",{
value: function () { // do not use arrow function
var N = [], L = [];
this.forEach(e => {
Number.isFinite(e) ? N.push(e) : L.push(e);
});
N.sort((a, b) => a - b);
L.sort();
[...N, ...L].forEach((v, i) => this[i] = v);
return this;
})
try a =[1,'u',"V",10,4,"c","A"].sort_mixed(); console.log(a)
If anyone doesn't understand how Array.sort() works with integers, read this answer.
Alphabetical order:
By default, the sort() method sorts the values as strings in alphabetical and ascending order.
const myArray = [104, 140000, 99];
myArray.sort();
console.log(myArray); // output is [104, 140000, 99]
Ascending order with array.sort(compareFunction):
const myArray = [104, 140000, 99];
myArray.sort(function(a, b){
return a - b;
});
console.log(myArray); // output is [99, 104, 140000]
Explanation from w3schools:
compareFunction defines an alternative sort order. The function should return a negative, zero, or positive value, depending on the arguments, like:
function(a, b){return a-b}
When the sort() method compares two values, it sends the values to the compare function, and sorts the values according to the returned (negative, zero, positive) value.
Example:
When comparing 40 and 100, the sort() method calls the compare
function(40,100).
The function calculates 40-100, and returns -60 (a negative value).
The sort function will sort 40 as a value lower than 100.
Descending order with array.sort(compareFunction):
const myArray = [104, 140000, 99];
myArray.sort(function(a, b){
return b - a;
});
console.log(myArray); // output is [140000, 104, 99]
This time we calculated with b - a(i.e., 100-40) which returns a positive value.
You can get height and lowest number simply by using max() and min() in-built function
var numArray = [140000, 104, 99];
console.log(Math.max(...numArray));
console.log(Math.min(...numArray));
If you want to sort in ascending or descending order
numArray.sort((a, b)=> a - b);
Know more
If you need to calculate and sort the largest charCodeAt from a list of string this is the right way.
const arrayLines = '1.1.1.1\n1.0.1.1\n1.1.1.2\n1.1.1.0'.split('\n');
// Response: (4) ['1.0.1.1', '1.1.1.0', '1.1.1.1', '1.1.1.2']
arrayLines.sort((a, b) => {
let a_charCodeSize = 0,
b_charCodeSize = 0;
// Loop true a & b characters and calculate the charCodeAt size.
for (const aChar of a) a_charCodeSize += aChar.charCodeAt(0);
for (const bChar of b) b_charCodeSize += bChar.charCodeAt(0);
return a_charCodeSize - b_charCodeSize;
});

Categories