I have an array of objects, let's say:
var objects = [
{name: 'A'},
{name: '1'},
{name: 'B'}
]
Knowing that I can sort it using Lodash sortBy:
objects= _.sortBy(objects, 'name')
which will result in this:
[
{name: '1'},
{name: 'A'},
{name: 'B'}
]
But my desired output is this:
[
{name: 'A'},
{name: 'B'},
{name: '1'}
]
Please help.
Using Array#sort
you can apply this logic:
// If both are numbers or both are not numbers
isNaN(a.name) === isNaN(b.name) ?
// then compare between them
a.name.localeCompare(b.name)
: // else
// If the 1st is not a number move it up, if it's a number move it down
(isNaN(a.name) ? -1 : 1);
Without lodash:
var objects = [{"name":"A"},{"name":"3"},{"name":"1"},{"name":"B"}];
objects.sort(function(a, b) {
return isNaN(a.name) === isNaN(b.name) ? a.name.localeCompare(b.name) : (isNaN(a.name) ? -1 : 1);
});
console.log(objects);
As part of a lodash's chain:
var objects = [{"name":"A"},{"name":"3"},{"name":"1"},{"name":"B"}];
var result = _(objects)
.sort(function(a, b) {
return isNaN(a.name) === isNaN(b.name) ? a.name.localeCompare(b.name) : (isNaN(a.name) ? -1 : 1);
})
.value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.3/lodash.min.js"></script>
I'm not sure if using lodash's sortBy
is the correct approach for this problem. Here's an implementation using Javascript's Array#sort
method.
It takes not only the first character but the entire string into account when doing the sorting.
const objects = [{
name: '2'
}, {
name: 'B'
}, {
name: '1'
}, {
name: 'A'
}, {
name: 'A1'
}, {
name: 'AA'
}]
objects.sort((o1, o2) => {
let a = o1.name, b = o2.name;
let isDigit = x => x >= 48 && x <= 57;
for (let i = 0, n = Math.min(a.length, b.length); i < n; i++) {
let aCharCode = a.charCodeAt(i), bCharCode = b.charCodeAt(i);
if (aCharCode !== bCharCode) {
if (isDigit(aCharCode) && !isDigit(bCharCode)) return 1;
if (isDigit(bCharCode) && !isDigit(aCharCode)) return -1;
return aCharCode - bCharCode;
}
}
return a.length - b.length;
});
console.log(objects)
For the given input, this prints out
[
{
"name": "A"
},
{
"name": "AA"
},
{
"name": "A1"
},
{
"name": "B"
},
{
"name": "1"
},
{
"name": "2"
}
]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With