0

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;
 });
};
asked Sep 15, 2016 at 12:50

1 Answer 1

2

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.

answered Sep 15, 2016 at 13:03
Sign up to request clarification or add additional context in comments.

2 Comments

Hmm, your way needs a newer version of javascript, doesnt it?
Yeah, but only lambda expressions, it's enough to convert them to callbacks in older version. Thanks!

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.