Sort javascript array alphanumerically [duplicate] - javascript

This question already has answers here:
Natural sort of alphanumerical strings in JavaScript
(6 answers)
Closed 4 years ago.
I have this array
const arr = ['1','2','3',...'30','31','LAST']
I need to sort by number ASC
Here is the example code and I don't know how to sort it.
help me please
const arr2 = ['2','1','10','LAST','20']
I need result ['1','2','10','20','LAST'] instead of ['1','10','2','20','LAST']

You could check for NaN and move that value to bottom.
Array#sort sorts without callback by string and does not respect stringed numerical values.
var array = ['2','ZIRST','1','10','LAST','20', 'Sara'];
array.sort((a, b) => isNaN(a) - isNaN(b) || a - b || a > b || -(a < b));
console.log(array);

function sortArray(arr) {
let sortedArr = arr.sort();
sortedArr.forEach((v, i) => {
if (!isNaN(parseInt(v))) {
sortedArr[i] = parseInt(v);
} else {
sortedArr[i] = v;
}
});
return sortedArr.sort((a, b) => a - b).map(String);
}
// tests
console.log(sortArray(['2', '1','10','LAST','20']));
console.log(sortArray(['5','ZIRST','1','10','LAST','20', 'Sara']));

You need to check whether the given element in the array is number or not and then sort it accordingly for numbers and strings. You can create a reusable function sortNumber so that it can be used for multiple arrays and you do not need to duplicate the same logic again and again.
function sortNumber(a,b) {
return isNaN(a) - isNaN(b) || a - b;
}
var inputArray = ['2','1','10','LAST','20'];
inputArray.sort(sortNumber);
console.log(inputArray);
inputArray = ['21','31','110','LAST','220'];
inputArray.sort(sortNumber);
console.log(inputArray);

You can use localeCompare to sort an array on the numeric property.
const array = ["1", "5", "10", "20", "ZERO", "LAST", "Sara"];
array.sort((a, b) => a.localeCompare(b,undefined,{numeric: true}));
console.log(array);

You can use custom comparator like this:
var arr = ['2','1','10','LAST','20'];
arr.sort((a,b)=>{
return parseInt(a) > parseInt(b) || isNaN(a);
});

Related

stopping a map or filter from iterating the last index

var arr = [1,2,3,4]
arr.map((x,i) => arr[i+1] - x)
// 1,1,1,NaN
Is there a way you can use the index in an Array.map or Array.filter method to compare value with-out comparing the final index to avoid the outcome of NaN?
You can use Array#slice to remove the last element before applying map.
var arr = [1,2,3,4]
console.log(arr.slice(0,-1).map((x,i) => arr[i+1] - x));
The shortest way you could do this would be
var mapped = arr.map((x,i) => arr[i+1] - x).filter(x => x);
Which is saying filter all the values where x is True
But I don't think you can do this with only map. I think map always returns an array of equal length.
You use reduce to achieve this though.
var arr = [1,2,3,4]
var reduced = arr.reduce((ids,x,i) => {
if (i < arr.length-1 ){
ids.push(arr[i+1] - x)
}
return ids
}, []);
console.log(reduced)
Outputs
[ 1, 1, 1 ]
Yes, you can. Just use Arra.filter() and return only the value that has a primitive value:
var arr = [1,2,3,4];
var newArr = arr.map((x,i) => arr[++i] - x)
.filter(val => val);
console.log(newArr);

sort array of objects with letters and numbers in descending order [duplicate]

This question already has answers here:
Sort array of objects by string property value
(57 answers)
Closed 4 years ago.
data = [{"map_name": "PHX7260.AE5020003.9"},
{"map_name": "PHX7260.AE5020003.10"},
{"map_name": "PHX7260.AE5020003.1"}]
I want to sort this data in descending order alphabetically and numerically both.
I tried the below but it doesn't work on array of objects.
var myArray = data;
var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
console.log(myArray.sort(collator.compare));
How should I go about it, the data of objects is received and it should be returned as objects only and not as array to display.
You can use array#sort with string#localeCompare with numeric property set to true.
const data = [{"map_name": "PHX7260.AE5020003.9"}, {"map_name": "PHX7260.AE5020003.10"},{"map_name": "PHX7260.AE5020003.1"}];
data.sort((a,b) => b.map_name.localeCompare(a.map_name, undefined, {numeric: true}));
console.log(data);
Using javascript's native Array.sort() method, you can split your strings on . and do a multi-step sort like below:
var data = [{"map_name": "PHX7260.AE5020003.9"},
{"map_name": "PHX7260.AE5020003.10"},
{"map_name": "PHX7260.AE5020003.1"}]
function compare(a,b){
if(!!parseInt(a) && !!parseInt(b)){
a = parseInt(a)
b = parseInt(b)
}
if(a > b) return 1
else if(a < b) return -1
else return 0
}
function sortData(a,b){
let a_arr = a.map_name.split('.'),
b_arr = b.map_name.split('.')
while(a_arr.length){
let val = compare(a_arr.shift(), b_arr.shift())
if(val) return val
}
return 0
}
console.log(data.sort(sortData))
You can get the string and the number before/after the last dot respectively.
Compare the string first, if they are equal sort by number else use the function localeCompare.
This approach sorts using descending direction.
Look how ZHX7260.AE5020003.10 is placed at the first position.
var data = [{"map_name": "PHX7260.AE5020003.9"}, {"map_name": "ZHX7260.AE5020003.10"}, {"map_name": "PHX7260.AE5020003.10"}, {"map_name": "PHX7260.AE5020003.1"}];
data.sort((a, b) => {
var astr = a.map_name.substring(0, a.map_name.lastIndexOf('.'));
var bstr = b.map_name.substring(0, b.map_name.lastIndexOf('.'));
if (astr === bstr) {
var aidx = a.map_name.substring(a.map_name.lastIndexOf('.') + 1);
var bidx = b.map_name.substring(b.map_name.lastIndexOf('.') + 1);
return bidx - aidx;
} else return bstr.localeCompare(astr);
});
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
also since PHX7260.AE5020003 are same hence the output expected is above , if the string aredifferent it should sort the string first and then the number

How use natural sorting in array of strings?

I have the following array and sort result:
['53-15-9', '53-15-10', '53-15-8'].sort() // => ["53-15-10", "53-15-8", "53-15-9"]
but I need to get the following result:
["53-15-8", "53-15-9", "53-15-10"];
How could I get desired result?
To compare numbers instead of strings, first remove '-'. When you use arithmetic
operation, JavaScript first coverts it to numbers.
'53-15-9'.replace(/-/g,'') gives '53159'. You can use closures in sort() to pass compare function that can simply subtract a from b. The following function will sort the array ascending:
['53-15-9', '53-15-10', '53-15-8'].sort(function(a,b){
return a.replace(/-/g,'') - b.replace(/-/g,'')
})
Update
As mentioned in the comments, '54-1-1' is less than '53-15-9'. We can change '54-1-1' to '54-01-01'. This only works in double digits. We can do it like:
function customSort(myArray) {
myArray = myArray.map(function(a,b){
var ar = a.split('-');
return ar.map(function(arK, arV){return (arK<10)?'0'+arK : arK.toString();}).join('-');;
})
return myArray.sort(function(a,b){
return a.replace(/-/g,'') - b.replace(/-/g,'')
});
}
customSort(['54-1-2','53-15-9', '53-15-10', '53-15-8']);
// => ["53-15-08", "53-15-09", "53-15-10", "54-01-02"]
You can use a custom function for splitting and sorting the parts.
var array = ['53-15-9', '53-15-10', '53-15-8'];
array.sort(function (a, b) {
var aa = a.split('-'),
bb = b.split('-'),
i, r = 0, l = Math.max(aa.length, bb.length);
for (i = 0; !r && i < l; i++) {
r = (aa[i] || 0) - (bb[i] || 0);
}
return r;
});
document.write('<pre>' + JSON.stringify(array, 0, 4) + '</pre>');
['53-15-9', '53-15-10', '53-15-8'].sort(function(a, b) {
var aNum = parseInt(a.replace(/-/g, ''));
var bNum = parseInt(b.replace(/-/g, ''));
return aNum < bNum ? -1 : aNum > bNum ? 1 : 0;
});
Assuming you want to sort them in numerical order including all the sections, simply remove the -, parse them as an int and then sort the ints in a custom sort function.
var arr = ['53-15-9', '53-15-10', '53-15-8'];
arr.sort(function(a,b){ return a.replace(/-/g,'') - b.replace(/-/g,'') });
console.log(arr);
output
["53-15-8", "53-15-9", "53-15-10"]
Try comparing every number separated by - using Array.prototype.every()
var arr = ["53-15-8", "53-15-9", "53-15-10"];
arr.sort(function(a, b) {
var curr = a.split(/-/).map(Number);
var next = b.split(/-/).map(Number);
return curr.every(function(val, key) {return val <= next[key]}) ? a : b
});
console.log(JSON.stringify(arr))
You need to define your own custom sorting function. Here is an example:
['53-15-9', '53-15-10', '53-15-8','2', '53-14-4','53-15-99'].sort(function(a,b){ // a and b are elements of the array
// split by - and convert values to number
a = a.split('-').map(function(val){return Number(val)})
b = b.split('-').map(function(val){return Number(val)})
// if one has less elements than another, we consider it should go first
if(a.length != b.length) return a.length > b.length
//else, one goes after another if one of its elements is greater than the others at that index
return a.some(function(val, index){
return val > b[index]
}) == 0 ? -1 : 1
})
//output: ["2", "53-14-4", "53-15-8", "53-15-9", "53-15-10", "53-15-99"]

Sort an array by its values

I have the following array.
var arr = ["1-5", "3-6", "2-4"];
Is there a way where I can sort like this:
var arr = ["1-5", "2-4", "3-6"]
I've tried with jquery map but cant because the values of array are not Numbers.
You can use sort function
Sort by first number
arr.sort(function (a, b) {
// a.split('-') - split a string into an array - ['1', '5']
// a.split('-')[0] - get first element - '1'
// "+" converts string to number - 1
// the same for "b"
return +a.split('-')[0] - +b.split('-')[0];
});
Example
Sort by second number
arr.sort(function (a, b) {
return +a.split('-')[1] - +b.split('-')[1];
});
Example
Use array sort. First the first num is compared. If they are equal, the second num is compared..
var arr = ["1-5", "3-6", "2-4"];
var sorted = arr.sort(function(a,b){
var numsA = a.split('-');
var numsB = b.split('-');
if (numsA[0]-numsB[0] !== 0){
return numsA[0] - numsB[0];
}
return numsA[1] - numsB[1];
});
document.write(sorted);
You can try the built in sort functionality arr.sort()
http://jsfiddle.net/qctg9cfx/
If sorting by the first number in the string, and also if the first number could itself be negative then a more robust solution may be to use parseInt.
var arr = ["1-5", "3-6", "-1-3", "2-4"];
arr.sort(function (a, b) {
return parseInt(a, 10) - parseInt(b, 10);
});
document.body.appendChild(document.createTextNode(JSON.stringify(arr)));

How to sort an array based on the length of each element?

I have an array like this:
arr = []
arr[0] = "ab"
arr[1] = "abcdefgh"
arr[2] = "abcd"
After sorting, the output array should be:
arr[0] = "abcdefgh"
arr[1] = "abcd"
arr[2] = "ab"
I want in the descending order of the length of each element.
You can use Array.sort method to sort the array. A sorting function that considers the length of string as the sorting criteria can be used as follows:
arr.sort(function(a, b){
// ASC -> a.length - b.length
// DESC -> b.length - a.length
return b.length - a.length;
});
Note: sorting ["a", "b", "c"] by length of string is not guaranteed to return ["a", "b", "c"]. According to the specs:
The sort is not necessarily stable (that is, elements that compare
equal do not necessarily remain in their original order).
If the objective is to sort by length then by dictionary order you must specify additional criteria:
["c", "a", "b"].sort(function(a, b) {
return a.length - b.length || // sort by length, if equal then
a.localeCompare(b); // sort by dictionary order
});
We can use Array.sort method to sort this array.
ES5 solution
var array = ["ab", "abcdefgh", "abcd"];
array.sort(function(a, b){return b.length - a.length});
console.log(JSON.stringify(array, null, '\t'));
For ascending sort order: a.length - b.length
For descending sort order: b.length - a.length
ES6 solution
Attention: not all browsers can understand ES6 code!
In ES6 we can use an arrow function expressions.
let array = ["ab", "abcdefgh", "abcd"];
array.sort((a, b) => b.length - a.length);
console.log(JSON.stringify(array, null, '\t'));
With modern JavaScript you can do like this:
Descending order
const arr = [
"ab",
"abcdefgh",
"abcd",
"abcdefghijklm"
];
arr.sort((a, b) => b.length - a.length);
console.log(JSON.stringify(arr, null, 2));
Ascending Order - Just switch the a with b
const arr = [
"ab",
"abcdefgh",
"abcd",
"abcdefghijklm"
];
arr.sort((a, b) => a.length - b.length);
console.log(JSON.stringify(arr, null, 2));
Here is the sort, depending on the length of a string with javascript using Bubble sort as you asked:
var arr = ['1234', '12', '12345', '1'];
bubbleSort(arr );
function bubbleSort(a) {
var swapped;
do {
swapped = false;
for (var i = 0; i < a.length - 1; i++) {
if (a[i].length < a[i + 1].length) {
var temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
swapped = true;
}
}
} while (swapped);
}
console.log(arr );
#created a sorting function to sort by length of elements of list
def sort_len(a):
num = len(a)
d = {}
i = 0
while i<num:
d[i] = len(a[i])
i += 1
b = list(d.values())
b.sort()
c = []
for i in b:
for j in range(num):
if j in list(d.keys()):
if d[j] == i:
c.append(a[j])
d.pop(j)
return c
If you want to preserve the order of the element with the same length as the original array, use bubble sort.
Input = ["ab","cdc","abcd","de"];
Output = ["ab","cd","cdc","abcd"]
Function:
function bubbleSort(strArray){
const arrayLength = Object.keys(strArray).length;
var swapp;
var newLen = arrayLength-1;
var sortedStrArrByLenght=strArray;
do {
swapp = false;
for (var i=0; i < newLen; i++)
{
if (sortedStrArrByLenght[i].length > sortedStrArrByLenght[i+1].length)
{
var temp = sortedStrArrByLenght[i];
sortedStrArrByLenght[i] = sortedStrArrByLenght[i+1];
sortedStrArrByLenght[i+1] = temp;
swapp = true;
}
}
newLen--;
} while (swap);
return sortedStrArrByLenght;
}
let arr = [5,2,100,1,20,3];
arr.sort((a,b)=>{
return a-b
})
console.log(arr) //[1, 2, 3, 5, 20, 100]
on the return value, the sort method will perform the functionality of swapping of an elements
return < 0 { i.e -ve number then a comes before b}
return > 0 { i.e +ve number then b comes before a}
return == 0 { order of a and b remains same }
Based on Salman's answer, I've written a small function to encapsulate it:
function sortArrayByLength(arr, ascYN) {
arr.sort(function (a, b) { // sort array by length of text
if (ascYN) return a.length - b.length; // ASC -> a - b
else return b.length - a.length; // DESC -> b - a
});
}
then just call it with
sortArrayByLength( myArray, true );
Note that unfortunately, functions can/should not be added to the Array prototype, as explained on this page.
Also, it modified the array passed as a parameter and doesn't return anything. This would force the duplication of the array and wouldn't be great for large arrays. If someone has a better idea, please do comment!
I adapted #shareef's answer to make it concise. I use,
.sort(function(arg1, arg2) { return arg1.length - arg2.length })
This code should do the trick:
var array = ["ab", "abcdefgh", "abcd"];
array.sort(function(a, b){return b.length - a.length});
console.log(JSON.stringify(array, null, '\t'));
let array = [`ab`, `abcdefgh`, `abcd`];
let newArray = array.sort((a,b) => {
return b.length - a.length
})
console.log(newArray);
Please the following code
<script>
arr = []
arr[0] = "ab"
arr[1] = "abcdefgh"
arr[2] = "sdfds"
arr.sort(function(a,b){
return a.length<b.length
})
document.write(arr)
</script>
The anonymous function that you pass to sort tells it how to sort the given array.hope this helps.I know this is confusing but you can tell the sort function how to sort the elements of the array by passing it a function as a parameter telling it what to do

Categories