I’m trying to sort only a subset of an array, the subset is a filtered version of that array, and I need the whole array (with the subset sorted ) as a result.
Here is the main array :
var data = [
{ name: "Cccc", sortCriteria: 1 },
{ name: "Bbbb", sortCriteria: 1 },
{ name: "Dddd", sortCriteria: 0 },
{ name: "Eeee", sortCriteria: 1 },
{ name: "Ffff", sortCriteria: 0 },
];
The sort criteria is used to filter the array :
var data2 = data.filter(function (attribute) {
return attribute.sortCriteria == 1;
});
Finally i’m sorting the filtered array :
var data3 = data2.sort(function (a, b) {
var aname = a.name.toLowerCase();
var bname = b.name.toLowerCase();
if (aname < bname) {
return -1;
}
if (aname > bname) {
return 1;
}
});
Every step works but data2 & data3 are subset only (i need the wole array) and data is obviously not sorted.
My result should be :
Bbbb
Cccc
Dddd
Eeee
Ffff
Any idea how that can be done using ecmascript 5 (the order can be random, this is a example) ?
Edit : the following question doesnt address my issue because it’s not ecma5 compliant.
5
Answers
You can store the original index of each element while filtering manually, then use those indexes to update the positions of the objects back in the original array.
First you have problem with your test data. If it’s sorted without even sortCriteria in mind the result will be the same. So I’ve changed the test data to make it more obvious.
We remember indices of items with sortCriteria, sort them and push back to data at remembered indices.
NOTICE: changed
Cccc
‘s sortCriteria to0
so it would be clear that it’s not sorted and stays at index0
, alsoBbbb
moved to the end so it should appear before `Eeee’ after the sorting:And a benchmark with test data x 15000.
When tested noticed that Nina’s solution’s performance drops exponentially.
ES6+ version:
Just add
if (!a.sortCriteria || !b.sortCriteria) return 0;
at the beginning of the sorting function to avoid sorting elements with sortCriteria 0. (Array.prototype.sort() sorts in-place, so there is no need tovar data2 = data.sort(...)
– data and data2 is the same array here.You could get an array of the items fro sorting and their indices and sort the indices an map a new array with either not sorted items or sorted items.