Reputation: 2024
I have the following structure:
var arrOfObjects = [
{
folder: {id: 2},
children: []
},
{
file: {id: 3},
children: []
},
{
file: {id: 4},
children: []
},
{
folder: {id: 1},
children: []
},
];
And I want to sort it using the following function call:
sortArrOfObjects(arrOfObjects, {
types: [
['file']
],
index: 'id',
order: 'asc'
});
sortArrOfObjects(arrOfObjects, {
types: [
['folder']
],
index: 'id',
order: 'asc'
});
The output would be sorted array of first files, and then folders, like:
var arrOfObjects = [
{
file: {id: 3},
children: []
},
{
file: {id: 4},
children: []
},
{
folder: {id: 1},
children: []
},
{
folder: {id: 2},
children: []
},
];
So I have the following function, calling sort()
built-in function on the array, and comparing objects where the given key exists, and skips iteration where the key does not exist in one of the comparators. But it doesn't work, it seems to sort in the completely wrong order. What's wrong?
function sortArrayOfObjects(arr, sortBy) {
arr.sort(function (a, b) {
var first = '';
var second = '';
for (var i = 0; i < sortBy.types.length; i++) {
switch (sortBy.types[i].length) {
case 1:
if (a[sortBy.types[i][0]] != undefined) {
first = a[sortBy.types[i][0]][sortBy.index].toString().toLowerCase();
} else {
return;
}
if (b[sortBy.types[i][0]] != undefined) {
second = b[sortBy.types[i][0]][sortBy.index].toString().toLowerCase();
} else {
return;
}
break;
case 2:
// not implemented yet
break;
default:
break;
}
}
if (first > second) {
return (sortBy.order == 'asc') ? 1 : -1;
}
if (first < second) {
return (sortBy.order == 'asc') ? -1 : 1;
}
return 0;
});
};
Upvotes: 0
Views: 58
Reputation: 214949
The technique called "decorate-sort-undecorate" makes jobs like this easy:
var arrOfObjects = [
{
folder: {id: 2},
children: []
},
{
file: {id: 3},
children: []
},
{
file: {id: 4},
children: []
},
{
folder: {id: 1},
children: []
},
];
result = arrOfObjects
.map(obj => ('file' in obj) ? [1, obj.file.id, obj] : [2, obj.folder.id, obj])
.sort((a, b) => a[0] - b[0] || a[1] - b[1])
.map(x => x[2]);
console.log(result)
Basically, we convert our array like [item, item...]
to an array [ [sort-keys, item], [sort-keys, item]...
, then sort that array and finally pull our items back - in the right order.
Upvotes: 2