0

I have an array of objects:

var data= [{
    "title": "All pages",
    "page": "all",

}, {
    "title": "Post with builder",
    "page": "pt_post_6188",

}, {
    "title": "Blog Categories",
    "page": "tx_category",

}, {
    "title": "Single Blog Posts",
    "page": "pt_post",

}];

and a sorting order array constructed out of the object item titles.

var order = ["Post with builder", "All pages", "Blog Categories", "Single Blog Posts"];

how do I sort the first array by the order array so that the new data turns out like this

var newdata= [{
    "title": "Post with builder",
    "page": "pt_post_6188",

}, {
    "title": "All pages",
    "page": "all",

}, {
    "title": "Blog Categories",
    "page": "tx_category",

}, {
    "title": "Single Blog Posts",
    "page": "pt_post",

}];

?

Not same as ref post. I am sorting by a specific order array without any specific logic.

Benn
  • 4,840
  • 8
  • 65
  • 106
  • 3
    [`data.sort((a, b) => order.indexOf(a.title) > order.indexOf(b.title));`](https://jsfiddle.net/tusharj/cq8yp4ns/) – Tushar Apr 09 '16 at 12:21
  • By what criteria is that sorting by? Alphabetically? No...Reversed alphabetically?...No...Am I missing something? – zer00ne Apr 09 '16 at 12:33
  • @zer00ne, sorting specific title order, collected in to an array – Benn Apr 09 '16 at 12:35
  • @Benn, ok so there's no logical order, it's just presenting the same data in an object as it is already ordered in the array. – zer00ne Apr 09 '16 at 12:39
  • @zer00ne, correct , no logic here , I am using UI sort and outputting an array for layouts, but their order needs to be specific since I am looping trough them and checking some params. – Benn Apr 09 '16 at 12:43
  • @Tushar Please don't recommend array searches inside each comparison of a sort. Too expensive. – Oriol Apr 09 '16 at 12:51
  • @Oriol You mean `indexOf` is expensive? – Tushar Apr 09 '16 at 12:54
  • @Tushar Exactly, it's linear. The proper way would be using data structures with sublilear operations, like ES6 maps. Usually objects are implemented as hashes, so they would work too (Nina's answer). – Oriol Apr 09 '16 at 12:57
  • Possible duplicate of [Sorting an array of JavaScript objects](http://stackoverflow.com/questions/979256/sorting-an-array-of-javascript-objects) – Dexygen Apr 10 '16 at 16:28

3 Answers3

1

You could use an object as hash table

{
    "Post with builder": 0,
    "All pages": 1,
    "Blog Categories": 2,
    "Single Blog Posts": 3
}

for the indices and sort with them.

var data = [{ "title": "All pages", "page": "all", }, { "title": "Post with builder", "page": "pt_post_6188", }, { "title": "Blog Categories", "page": "tx_category", }, { "title": "Single Blog Posts", "page": "pt_post", }],
    order = ["Post with builder", "All pages", "Blog Categories", "Single Blog Posts"],
    orderObject = {};

order.forEach(function (a, i) {
    orderObject[a] = i;
})

data.sort(function (a, b) {
    return orderObject[a.title] - orderObject[b.title];
});

document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>');
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

Since you already have the order arrays indexes for your ordering reference as a kind of hash, we may very simply use them like;

sorted = Array(order.length);
data.forEach((c,i) => sorted[order.indexOf(c.title)] = c);
Redu
  • 25,060
  • 6
  • 56
  • 76
0

// Using loadash

var data= [{
"title": "All pages",
"page": "all",
}, {
"title": "Post with builder",
"page": "pt_post_6188",
}, {
"title": "Blog Categories",
"page": "tx_category",
}, {
"title": "Single Blog Posts",
"page": "pt_post",
}];

var order = ["Post with builder", "All pages", "Blog Categories", "Single Blog Posts"];

function (data, order){
 return _.reduce(order, function (output, v) {
  output.push(_.filter(data,{title:v})[0]);
  return output;
 },[]);
}
Devank
  • 159
  • 2
  • 9