Sort array on key value - javascript

I have a function which sorts by name currently and an array of value / key pairs.
I wonder how can I pass the key on which sort is being performed so I can call the same function every time like so:
var arr = [{name:'bob', artist:'rudy'},
{name:'johhny', artist:'drusko'},
{name:'tiff', artist:'needell'},
{name:'top', artist:'gear'}];
sort(arr, 'name'); //trying to sort by name
sort(arr, 'artist'); //trying to sort by artist
function sort(arr) {
arr.sort(function(a, b) {
var nameA=a.name.toLowerCase(), nameB=b.name.toLowerCase();
if (nameA < nameB) //sort string ascending
return -1;
if (nameA > nameB)
return 1;
return 0; //default return value (no sorting)
});
}

Array.prototype.sortOn = function(key){
this.sort(function(a, b){
if(a[key] < b[key]){
return -1;
}else if(a[key] > b[key]){
return 1;
}
return 0;
});
}
var arr = [{name:'bob', artist:'rudy'},{name:'johhny', artist:'drusko'},{name:'tiff', artist:'needell'},{name:'top', artist:'gear'}];
arr.sortOn("name");
arr.sortOn("artist");

[edit 2020/08/14] This was rather an old answer and not very good as well, so simplified and revised.
Create a function that returns the sorting lambda (the Array.prototype.sort callback that does the actual sorting). That function can receive the key name, the kind of sorting (string (case sensitive or not) or numeric) and the sorting order (ascending/descending). The lambda uses the parameter values (closure) to determine how to sort.
const log = (...strs) =>
document.querySelector("pre").textContent += `\n${strs.join("\n")}`;
const showSortedValues = (arr, key) =>
` => ${arr.reduce((acc, val) => ([...acc, val[key]]), [])}`;
// the actual sort lamda factory function
const sortOnKey = (key, string, desc) => {
const caseInsensitive = string && string === "CI";
return (a, b) => {
a = caseInsensitive ? a[key].toLowerCase() : a[key];
b = caseInsensitive ? b[key].toLowerCase() : b[key];
if (string) {
return desc ? b.localeCompare(a) : a.localeCompare(b);
}
return desc ? b - a : a - b;
}
};
// a few examples
const onNameStringAscendingCaseSensitive =
getTestArray().sort( sortOnKey("name", true) );
const onNameStringAscendingCaseInsensitive =
getTestArray().sort( sortOnKey("name", "CI", true) );
const onValueNumericDescending =
getTestArray().sort( sortOnKey("value", false, true) );
// examples
log(`*key = name, string ascending case sensitive`,
showSortedValues(onNameStringAscendingCaseSensitive, "name")
);
log(`\n*key = name, string descending case insensitive`,
showSortedValues(onNameStringAscendingCaseInsensitive, "name")
);
log(`\n*key = value, numeric desc`,
showSortedValues(onValueNumericDescending, "value")
);
function getTestArray() {
return [{
name: 'Bob',
artist: 'Rudy',
value: 23,
}, {
name: 'John',
artist: 'Drusko',
value: 123,
}, {
name: 'Tiff',
artist: 'Needell',
value: 1123,
}, {
name: 'Top',
artist: 'Gear',
value: 11123,
}, {
name: 'john',
artist: 'Johanson',
value: 12,
}, ];
}
<pre></pre>

function keysrt(key) {
return function(a,b){
if (a[key] > b[key]) return 1;
if (a[key] < b[key]) return -1;
return 0;
}
}
someArrayOfObjects.sort(keysrt('text'));

Make your life easy and use a closure
https://stackoverflow.com/a/31846142/1001405
You can see the working example here
var filter = 'name', //sort by name
data = [{name:'bob', artist:'rudy'},{name:'johhny', artist:'drusko'},{name:'tiff', artist:'needell'},{name:'top', artist:'gear'}];;
var compare = function (filter) {
return function (a,b) { //closure
var a = a[filter],
b = b[filter];
if (a < b) {
return -1;
}else if (a > b) {
return 1;
} else {
return 0;
}
};
};
filter = compare(filter); //set filter
console.log(data.sort(filter));

Looking at all the answers, I came up with my own solution that works cross-browser. The accepted solution does not work in IE or Safari. Also, the other solutions do not allow for sorting by descending.
/*! FUNCTION: ARRAY.KEYSORT(); **/
Array.prototype.keySort = function(key, desc){
this.sort(function(a, b) {
var result = desc ? (a[key] < b[key]) : (a[key] > b[key]);
return result ? 1 : -1;
});
return this;
}
var arr = [{name:'bob', artist:'rudy'}, {name:'johhny', artist:'drusko'}, {name:'tiff', artist:'needell'}, {name:'top', artist:'gear'}];
arr.keySort('artist');
arr.keySort('artist', true);

Related

d3 js sort error in chrome [duplicate]

I have an array of objects to sort. Each object has two parameters: Strength and Name
objects = []
object[0] = {strength: 3, name: "Leo"}
object[1] = {strength: 3, name: "Mike"}
I want to sort first by Strength and then by name alphabetically. I am using the following code to sort by the first parameter. How do I sort then by the second?
function sortF(ob1,ob2) {
if (ob1.strength > ob2.strength) {return 1}
else if (ob1.strength < ob2.strength){return -1}
return 0;
};
Thanks for your help.
(I am using Array.sort() with the aforementioned sortF as the sort comparison function passed into it.)
Expand your sort function to be like this;
function sortF(ob1,ob2) {
if (ob1.strength > ob2.strength) {
return 1;
} else if (ob1.strength < ob2.strength) {
return -1;
}
// Else go to the 2nd item
if (ob1.name < ob2.name) {
return -1;
} else if (ob1.name > ob2.name) {
return 1
} else { // nothing to split them
return 0;
}
}
A < and > comparison on strings is an alphabetic comparison.
This little function is often handy when sorting by multiple keys:
cmp = function(a, b) {
if (a > b) return +1;
if (a < b) return -1;
return 0;
}
or, more concisely,
cmp = (a, b) => (a > b) - (a < b)
Which works because in javascript:
true - true // gives 0
false - false // gives 0
true - false // gives 1
false - true // gives -1
Apply it like this:
array.sort(function(a, b) {
return cmp(a.strength,b.strength) || cmp(a.name,b.name)
})
Javascript is really missing Ruby's spaceship operator, which makes such comparisons extremely elegant.
You could chain the sort order with logical OR.
objects.sort(function (a, b) {
return a.strength - b.strength || a.name.localeCompare(b.name);
});
When I was looking for an answer to this very question, the answers I found on StackOverflow weren't really what I hoped for. So I created a simple, reusable function that does exactly this. It allows you to use the standard Array.sort, but with firstBy().thenBy().thenBy() style.
https://github.com/Teun/thenBy.js
PS. This is the second time I post this. The first time was removed by a moderator saying "Please don't make promotional posts for your own work". I'm not sure what the rules are here, but I was trying to answer this question. I'm very sorry that it is my own work. Feel free to remove again, but please point me to the rule involved then.
steve's answer, but prettier.
objects.sort(function(a,b)
{
if(a.strength > b.strength) {return 1;}
if(a.strength < b.strength) {return -1;}
if(a.name > b.name ) {return 1;}
if(a.name < b.name ) {return -1;}
return 0;
}
function sortF(ob1,ob2) {
if (ob1.strength > ob2.strength) {return 1}
else if (ob1.strength < ob2.strength) {return -1}
else if (ob1.name > ob2.name) {return 1}
return -1;
};
EDIT: Sort by strength, then if strength is equal, sort by name.
The case where strength and name are equal in both objects doesn't need to be accounted for seperately, since the final return of -1 indicates a less-than-or-equal-to relationship. The outcome of the sort will be correct. It might make it run faster or slower, I don't know. If you want to be explicit, just replace
return -1;
with
else if (ob1.name < ob2.name) {return -1}
return 0;
Find 'sortFn' function below. This function sorts by unlimited number of parameters(such as in c#: SortBy(...).ThenBy(...).ThenByDesc(...)).
function sortFn() {
var sortByProps = Array.prototype.slice.call(arguments),
cmpFn = function(left, right, sortOrder) {
var sortMultiplier = sortOrder === "asc" ? 1 : -1;
if (left > right) {
return +1 * sortMultiplier;
}
if (left < right) {
return -1 * sortMultiplier;
}
return 0;
};
return function(sortLeft, sortRight) {
// get value from object by complex key
var getValueByStr = function(obj, path) {
var i, len;
//prepare keys
path = path.replace('[', '.');
path = path.replace(']', '');
path = path.split('.');
len = path.length;
for (i = 0; i < len; i++) {
if (!obj || typeof obj !== 'object') {
return obj;
}
obj = obj[path[i]];
}
return obj;
};
return sortByProps.map(function(property) {
return cmpFn(getValueByStr(sortLeft, property.prop), getValueByStr(sortRight, property.prop), property.sortOrder);
}).reduceRight(function(left, right) {
return right || left;
});
};
}
var arr = [{
name: 'marry',
LocalizedData: {
'en-US': {
Value: 10000
}
}
}, {
name: 'larry',
LocalizedData: {
'en-US': {
Value: 2
}
}
}, {
name: 'marry',
LocalizedData: {
'en-US': {
Value: 100
}
}
}, {
name: 'larry',
LocalizedData: {
'en-US': {
Value: 1
}
}
}];
document.getElementsByTagName('pre')[0].innerText = JSON.stringify(arr)
arr.sort(sortFn({
prop: "name",
sortOrder: "asc"
}, {
prop: "LocalizedData[en-US].Value",
sortOrder: "desc"
}));
document.getElementsByTagName('pre')[1].innerText = JSON.stringify(arr)
pre {
font-family: "Courier New" Courier monospace;
white-space: pre-wrap;
}
Before:
<pre></pre>
Result:
<pre></pre>
With ES6 you can do
array.sort(function(a, b) {
return SortFn(a.strength,b.strength) || SortFn(a.name,b.name)
})
private sortFn(a, b): number {
return a === b ? 0 : a < b ? -1 : 1;
}
Here is the function I use. It will do an arbitrary number.
function Sorter(){
var self = this;
this.sortDefs = [];
for (let i = 0; i < arguments.length; i++) {
// Runs 5 times, with values of step 0 through 4.
this.sortDefs.push(arguments[i]);
}
this.sort = function(a, b){
for (let i = 0; i < self.sortDefs.length; i++) {
if (a[self.sortDefs[i]] < b[self.sortDefs[i]]) {
return -1;
} else if (a[self.sortDefs[i]] > b[self.sortDefs[i]]) {
return 1
}
}
return 0;
}
}
data.sort(new Sorter('category','name').sort);
In 2018 you can use just sort() ES6 function, that do exactly, what you want.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

how to sort data on the basis of count field in data array?

function getFrequency(str){
var sorted = str.split("").sort();
var data = [];
for(var i = 0; i <sorted.length; i++){
var last = data[data.length - 1]
if(last && last.character === sorted[i]) last.count++;
else data.push({character : sorted[i], count: 1});
}
return data;
}
it returns an array that consists of characters and their count. I want to arrange these in descending order of count. What to do?
You could sort the data array and use the property count for taking the delta as return value.
data.sort((a, b) => b.count - a.count);
function getFrequency(str){
var sorted = str.split("").sort(),
data = [],
i,
last;
for (i = 0; i < sorted.length; i++){
last = data[data.length - 1];
if (last && last.character === sorted[i]) {
last.count++;
} else {
data.push({ character: sorted[i], count: 1 });
}
}
return data.sort((a, b) => b.count - a.count);
}
console.log(getFrequency('zzzwwwwwabcdabaa'))
.as-console-wrapper { max-height: 100% !important; top: 0; }
Sort data based on count prop.
function getFrequency(str){
var sorted = str.split("").sort();
var data = [];
for(var i = 0; i <sorted.length; i++){
var last = data[data.length - 1]
if(last && last.character === sorted[i]) last.count++;
else data.push({character : sorted[i], count: 1});
}
data = data.sort(function(a,b){
return b.count - a.count
});
return data;
}
console.log( getFrequency('aaaabddyww') )
You could use reduce() to create an object for each character and add it to an array.
function getFrequency(str) {
var chars = str.split("");
return chars.reduce((a, c) => {
var f = a.find(e => e.character === c);
if (f) f.count++;
else a.push({
character: c,
count: 1
});
return a;
}, []);
}
console.log(getFrequency('zzzwwwwwabcdabaa'))
Reduce the string into an object of characters and counts. Convert to an array using Object.values(), then sort by b.count - a.count:
function getFrequency(str) {
return Object.values(str.split('')
.reduce(function(r, c) {
r[c] = r[c] || { character: c, count: 0 };
r[c].count += 1;
return r;
}, Object.create(null))
).sort(function(a, b) {
return b.count - a.count;
});
}
console.log(getFrequency('who let the dogs out who who'));

Sort a Javascript Object by Key, then by named property

I am having trouble into sorting the following Object by KEY (DESC).
Then, sorting each item by the "notesList.id" property (DESC).
Expected order
"2017/04/17"
"2017/03/14"
"2017/02/30"
Then, for the "2017/04/17" notesList items, here is the Expected order :
id:57
id:48
id:12
The JS Object
var myNotes = {
"customNotes":{
"2017/04/17":{
"concernedDate":"2017/04/17",
"notesList":[
{
"id":48,
"title":"Title 48"
},
{
"id":12,
"title":"Title 12"
},
{
"id":57,
"title":"Title 57"
}
]
},
"2017/02/30":{
"concernedDate":"2017/02/30",
"notesList":[
{
"id":92,
"title":"Title 92"
}
]
},
"2017/03/14":{
"concernedDate":"2017/03/14",
"notesList":[
{
"id":92,
"title":"Title 92"
}
]
}
}
}
The Script
//Convert the OBJECT to an ARRAY
var tmpArr = Object.keys(myNotes.customNotes);
//Sort (Not working)
tmpArr.sort((a, b) => a > b ? a : b);
//Convert back the ARRAY to an OBJECT
Object.keys(myNotes.customNotes).sort((a, b) => a > b ? a : b).map(k => myNotes.customNotes[k]);
What am I missing ? I thank you very much
I observe a few things that seem out of place in your code.
tmpArr.sort((a, b) => a > b ? a : b); returns a sorted version of tmpArr. it will not modify myNotes object.
Object.keys(myNotes.customNotes).sort(... will return an array of objects from myNotes.customNotes, and not an object that has the same structure as myNotes like you intended.
In the code above, you are not sorting notesList.
Suppose you want to to get an array, all you need is to fix your sort function and also sort your notesList in the map function. So your code should look like this:
var myNotes={customNotes:{"2017/04/17":{concernedDate:"2017/04/17",notesList:[{id:48,title:"Title 48"},{id:12,title:"Title 12"},{id:57,title:"Title 57"}]},"2017/02/30":{concernedDate:"2017/02/30",notesList:[{id:92,title:"Title 92"}]},"2017/03/14":{concernedDate:"2017/03/14",notesList:[{id:92,title:"Title 92"}]}}};
var res = Object.keys(myNotes.customNotes)
.sort((a, b) => a < b)
.map(k => {
let currNote = myNotes.customNotes[k];
currNote.notesList.sort((a, b) => a.id < b.id)
return myNotes.customNotes[k];
});
console.log(res);
But, if you intend to keep the structure of myNotes, I would suggest that you use reduce function. See my code below:
var myNotes={customNotes:{"2017/04/17":{concernedDate:"2017/04/17",notesList:[{id:48,title:"Title 48"},{id:12,title:"Title 12"},{id:57,title:"Title 57"}]},"2017/02/30":{concernedDate:"2017/02/30",notesList:[{id:92,title:"Title 92"}]},"2017/03/14":{concernedDate:"2017/03/14",notesList:[{id:92,title:"Title 92"}]}}};
// MY SOLUTION
var sortedNotes = Object.keys(myNotes.customNotes)
.sort((a, b) => a < b)
.reduce((acc, val, _, arr) => {
acc[val] = myNotes.customNotes[val];
acc[val].notesList.sort((a, b) => a.id < b.id);
return acc;
},{});
console.log(sortedNotes);
You can use thenBy.js
Like this
data.sort(
firstBy(function (v1, v2) { return v1.name.length - v2.name.length; })
.thenBy(function (v1, v2) { return v1.population - v2.population; })
.thenBy(function (v1, v2) { return v1.id - v2.id; })
);
You can also sort by property name by using this library
Like this
data.sort(
firstBy(function (v) { return v.name.length; })
.thenBy("population")
.thenBy("id")
);
Your sort function should return either zero, a positive number or a negative number. You are just returning the values. Also note that this will convert your customNotes into an array, since objects cannot be sorted. If you do not wish that to happen, you can maintain another key with a sorted array of the keys in customNotes and use this array to look up the values in customNotes. Another approach would be to use the new Map object. Map supports sorted keys.
Try this:
var myNotes = {
"customNotes":{
"2017/04/17":{
"concernedDate":"2017/04/17",
"notesList":[
{
"id":48,
"title":"Title 48"
},
{
"id":12,
"title":"Title 12"
},
{
"id":57,
"title":"Title 57"
}
]
},
"2017/02/30":{
"concernedDate":"2017/02/30",
"notesList":[
{
"id":92,
"title":"Title 92"
}
]
},
"2017/03/14":{
"concernedDate":"2017/03/14",
"notesList":[
{
"id":92,
"title":"Title 92"
}
]
}
}
}
var myNewNotes = {};
myNewNotes.customNotes = Object.keys(myNotes.customNotes).sort((a, b) => {
if (a < b) return -1
else if (a > b) return 1;
else return 0;
}).map(key => sorted(myNotes.customNotes[key]));
function sorted(note) {
note.notesList = note.notesList.sort((a, b) => {
if (a.id < b.id) return -1;
else if (a.id > b.id) return 1;
else return 0;
})
return note;
}
console.log(myNewNotes)

Sort an Array of Objects based on key, and based on value

Consider this:
[{name:'John'},{age:25},{address:'some street'}]
As you can see none of the keys are a consistent name, so I cannot use.
arr.sort((a,b)=> a.consistentKey < b.consistentKey);
How can I go about sorting something like this, by name, and by value?
so the following sorted by key in alphabetical order should be:
[{address:'some street'},{age:25},{name:'John'}]
If you are thinking of sorting on the basis of key first and then further on values, you can try the following :
var a = [{name:'John'},{age:25},{address:'some street'}];
alert(JSON.stringify(a.sort((a, b) => {
nameA = Object.keys(a)[0];
nameB = Object.keys(b)[0];
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
})));
Here I have considered only one key, but you can always extend it to multiple keys and similarly you can further sort on the basis of values too.
If you extract the key name using Object.keys, then you can get the values you need to perform the comparison:
[{name: 'John'}, {age: 25}, {address:'some street'}].sort((a, b) => {
const keyA = Object.keys(a)[0]
const valA = a[keyA]
const keyB = Object.keys(b)[0]
const valB = a[keyB]
if (keyA > keyB) {
return 1
} else if (keyA < keyB) {
return -1
} else /* equal */ {
if (valA > valB) {
return 1
} else if (valA < valB) {
return -1
} else /* equal */ {
return 0
}
}
})
You can do this with
input.sort((a, b) => {
const keya = Object.keys(a)[0];
const keyb = Object.keys(b)[0];
return keya.localeCompare(keyb) || a[keya].localeCompare(b[keyb]);
});
Using localeCompare is both shorter and more robust in the face of different language locales.
Below is the solution I would use. This solution provides a keys only sort, a values only sort, a keys then values sort, and a values then keys sort.
class FunkySort {
sort (sortType) {
switch (sortType) {
case 'keysOnly':
return data => this._sortByKey(data);
case 'valuesOnly':
return data => this._sortByValue(data);
case 'valuesPrimary':
return data => {
data = this._sortByKey(data);
return this._sortByValue(data);
};
case 'keysPrimary':
return data => {
data = this._sortByValue(data);
return this._sortByKey(data);
};
}
}
_sortByKey (data) {
return data.sort((a, b) => {
var keyA = Object.keys(a)[0];
var keyB = Object.keys(b)[0];
return keyA < keyB ? -1 : keyA > keyB ? 1 : 0;
});
}
_sortByValue (data) {
return data.sort((a, b) => {
// note that in Node >=v7 you could use `Object.values()`, but not in <v7.0
var valueA = a[Object.keys(a)[0]];
var valueB = b[Object.keys(b)[0]];
return valueA < valueB ? -1 : valueA > valueB ? 1 : 0;
});
}
}
const dataArr = [{name:'John'},{age:25},{address:'some street'}];
const fs = new FunkySort();
fs.sort('keysPrimary')(dataArr);
Note that fs.sort is a curried function. The first call sets the type of sort to be done, so fs.sort('keysPrimary') returns a function that takes an array of objects and sorts it first by the values, and then by the keys, resulting in an array of objects sorted by key, and if there are multiple objects with the same key, those are sorted by value.
If you don't need this level of flexibility in the type of sort, then just the _sortByKey helper method should suffice.

Sort an array so that null values always come last

I need to sort an array of strings, but I need it so that null is always last. For example, the array:
var arr = [a, b, null, d, null]
When sorted ascending I need it to be sorted like [a, b, d, null, null] and when sorted descending I need it to be sorted like [d, b, a, null, null].
Is this possible? I tried the solution found below but it's not quite what I need.
How can one compare string and numeric values (respecting negative values, with null always last)?
Check out .sort() and do it with custom sorting.
Example
function alphabetically(ascending) {
return function (a, b) {
// equal items sort equally
if (a === b) {
return 0;
}
// nulls sort after anything else
if (a === null) {
return 1;
}
if (b === null) {
return -1;
}
// otherwise, if we're ascending, lowest sorts first
if (ascending) {
return a < b ? -1 : 1;
}
// if descending, highest sorts first
return a < b ? 1 : -1;
};
}
var arr = [null, "a", "z", null, "b"];
console.log(arr.sort(alphabetically(true)));
console.log(arr.sort(alphabetically(false)));
Use a custom compare function that discriminates against null values:
arr.sort(function(a, b) {
return (a===null)-(b===null) || +(a>b)||-(a<b);
});
For descending order of the non-null values, just swap a and b in the direct comparison:
arr.sort(function(a, b) {
return (a===null)-(b===null) || -(a>b)||+(a<b);
});
Ascending
arr.sort((a, b) => (a != null ? a : Infinity) - (b != null ? b : Infinity))
Descending
arr.sort((a, b) => (b != null ? b : -Infinity) - (a != null ? a : -Infinity))
(For descending order if you don't have negative values in the array, I recommend to use 0 instead of -Infinity)
The simplest approach is to handle null first, then deal with non-null cases based on the desired order:
function sortnull(arr, ascending) {
// default to ascending
if (typeof(ascending) === "undefined")
ascending = true;
const multiplier = ascending ? 1 : -1;
const sorter = function(a, b) {
if (a === b) // identical? return 0
return 0;
else if (a === null) // a is null? last
return 1;
else if (b === null) // b is null? last
return -1;
else // compare, negate if descending
return a.localeCompare(b) * multiplier;
}
return arr.sort(sorter);
}
const arr = ["a", "b", null, "d", null];
console.log(sortnull(arr)); // ascending ["a", "b", "d", null, null]
console.log(sortnull(arr, true)); // ascending ["a", "b", "d", null, null]
console.log(sortnull(arr, false)); // descending ["d", "b", "a", null, null]
If you need natural sorting for numbers, or any of the options provided by Collator (including speed enhancements and respecting locale), try this approach, based off of Paul Roub's solution, cleaned up a bit. We almost always use numeric sorting, hence the defaults...
If you are not a Typescript fan, just strip off the :type specs or copy from the snippet.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator
const naturalCollator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
const alphabeticCollator = new Intl.Collator(undefined, {});
function nullSort(descending: boolean = false, alphabetic: boolean = false) {
return function (a: any, b: any): number {
if (a === b) {
return 0;
}
if (a === null) {
return 1;
}
if (b === null) {
return -1;
}
let ret
if (alphabetic) {
ret = alphabeticCollator.compare(a, b)
} else {
ret = naturalCollator.compare(a, b)
}
if (descending) {
ret = -ret
}
return ret
};
}
Use it like this.
// numeric, ascending (default)
myList.sort(nullSort());
// alphabetic, descending
myList.sort(nullSort(true, true));
You can modify the factory method to take a collator instead, for greater flexibility.
function nullSort(descending: boolean = false, collator: Collator = naturalCollator)
Working Snippet
const naturalCollator = new Intl.Collator(undefined, {
numeric: true,
sensitivity: 'base'
});
const alphabeticCollator = new Intl.Collator(undefined, {});
function nullSort(descending = false, alphabetic = false) {
return function(a, b) {
if (a === b) {
return 0;
}
if (a === null) {
return 1;
}
if (b === null) {
return -1;
}
let ret
if (alphabetic) {
ret = alphabeticCollator.compare(a, b)
} else {
ret = naturalCollator.compare(a, b)
}
if (descending) {
ret = -ret
}
return ret
};
}
const items = [null, 10, 1, 100, null, 'hello', .1, null]
console.log(items.sort(nullSort()));
like this, note: this will only push the null's to the back
var arr = ["a", null, "b"];
var arrSor = [];
arr.forEach(function (el) {
if (el === null) {
arrSor.push(el);
} else {
arrSor.unshift(el);
}
});
Do it like:
var arr = [a, b, null, d, null]
foreach ($arr as $key => $value) {
if($value == null)
unset($arr[$key]);
$arr[] = $value;
}
// rebuild array index
$arr = array_values($arr);
echo '<pre>';print_r($arr);die;
I am sorting objects with a custom index and this works for me. I am not wanting to change the original array and it is important to keep the null indexes where they are.
let sorted = [...array].sort((a, b) => {
if (!a || !b) return 0;
else return a.CustomIndex - b.CustomIndex;
});
function sortNumsAsc(arr) {
if(arr === null || arr === []) {
return [];
}
else {
return arr.sort(function(a,b){return a-b});
//return newarr;
}
}
console.log(sortNumsAs([801, 19, 4, 5, -4, 85]))

Categories

Resources