Created
December 2, 2011 15:40
-
Star
(109)
You must be signed in to star a gist -
Fork
(22)
You must be signed in to fork a gist
-
-
Save ecarter/1423674 to your computer and use it in GitHub Desktop.
Order an array of objects based on another array order
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Sort array of objects based on another array | |
*/ | |
function mapOrder (array, order, key) { | |
array.sort( function (a, b) { | |
var A = a[key], B = b[key]; | |
if (order.indexOf(A) > order.indexOf(B)) { | |
return 1; | |
} else { | |
return -1; | |
} | |
}); | |
return array; | |
}; | |
/** | |
* Example: | |
*/ | |
var item_array, item_order, ordered_array; | |
item_array = [ | |
{ id: 2, label: 'Two' } | |
, { id: 3, label: 'Three' } | |
, { id: 5, label: 'Five' } | |
, { id: 4, label: 'Four' } | |
, { id: 1, label: 'One'} | |
]; | |
item_order = [1,2,3,4,5]; | |
ordered_array = mapOrder(item_array, item_order, 'id'); | |
console.log('Ordered:', JSON.stringify(ordered_array)); |
I made this based off of the OP.
This will sort according to your specified order. It will also sort and add unknown items to the end (a feature the original should've included).
/**
* Order an array of objects by another array.
* @param {array} array The array of objects to sort.
* @param {array} order The array of property names to order the objects by.
* @param {string} property The property name to use as a sorting target.
*/
function mapOrder(array, order, property) {
let ordered = [], unordered = [];
// Iterate over each item in the supplied array of objects, separating ordered and unordered objects into their own arrays.
array.forEach((item) => {
if (order.indexOf(item[property]) === -1) {
unordered.push(item);
} else {
ordered.push(item);
}
});
// Sort the ordered array.
ordered.sort((a, b) => {
a = a[property], b = b[property];
if (order.indexOf(a) < order.indexOf(b)) {
return -1;
} else {
return 1;
}
});
// Sort the unordered array.
unordered.sort((a, b) => {
a = a[property], b = b[property];
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return 0;
}
});
// Append the sorted, non-ordered array to the sorted, ordered array.
ordered.push(...unordered);
return ordered;
}
why not use
function mapOrder(array, order, key) {
return array.sort((a, b) =>
order.indexOf(a[key]) > order.indexOf(b[key]) ? 1 : -1
);
}
why not use
export function mapOrder(array, order, key) { array.sort((a, b) => { order.indexOf(a[key]) > order.indexOf(b[key]) ? 1 : -1; }); return array; }
@TheOneWayTruth u just copy author solution and forgot about return of order comparison. U solution does not work.
And u can return result of array.sort
without last return array
.
const mapOrder = (array, order, key) =>
array.sort((a, b) => order.indexOf(a[key]) > order.indexOf(b[key]) ? 1 : -1)
But it still topic starter solution.
Finally I got what I was looking for. Thanks @kkoo95
Here is the code If you want to move unmated rest of items at the end of array.
export const mapOrder = <T>(array: T[], order: any[], key: keyof T) => {
return array.sort((a, b) => {
let weightA = 0;
let weightB = 0;
if (!order.includes(a[key])) {
weightA += 100;
}
if (!order.includes(b[key])) {
weightB += 100;
}
return order.indexOf(a[key]) + weightA - (order.indexOf(b[key]) + weightB);
});
};
Test Case
const item_array = [
{ id: 2, label: "Two" },
{ id: 3, label: "Three" },
{ id: 5, label: "Five" },
{ id: 4, label: "Four" },
{ id: 1, label: "One" }
];
const item_order = [1, 5];
const ordered_array = mapOrder(item_array, item_order, "id");
console.log("Ordered:", JSON.stringify(ordered_array));
// Ordered: [{"id":1,"label":"One"},{"id":5,"label":"Five"},{"id":2,"label":"Two"},{"id":3,"label":"Three"},{"id":4,"label":"Four"}]
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@ArtemeeSenin it doesn't play well with non-existant values. At least for my use case.
with an array like this
['e', 'a', 'b', 'g', 'c', 'h', 'b', null, 'c', 'i', 'a', 'd']
,it gives
['e', 'g', 'h', null, 'i', 'd', 'a', 'a', 'b', 'b', 'c', 'c']
But I would expect to have all unknown stuff at the end, sorted ascendingly. but here it just stack them off in front