2
[
 {name:"foo", value:"1", order:"1.1.12"},
 {name:"foo bar", value:"2", order:"2.10.1"},
 {name:"bar", value:"3", order:"1.11.5"},
 {name:"baz", value:"4", order:"2.6.2"},
 {name:"foo baz", value:"5", order:"1.3.10"}
]

How can i sort this list by order with the help of underscore.js (or without). so i will end up with this:

[
 {name:"a", value:"1", order:"1.1.12"},
 {name:"a", value:"5", order:"1.3.10"},
 {name:"a", value:"3", order:"1.11.5"},
 {name:"a", value:"4", order:"2.6.2"},
 {name:"a", value:"2", order:"2.10.1"}  
]

It's worth mentioning that order could be any digit long for example it could be:

1.1
2
3.1.2.3 

so the solution has to be generic as possiable.

baba-dev
  • 2,582
  • 6
  • 27
  • 32

2 Answers2

3

You can split the string into an array of numbers and compare the numbers on the same position until you find something different:

var arr = [
 {name:"foo", value:"1", order:"1.1.12"},
 {name:"foo bar", value:"2", order:"2.10.1"},
 {name:"bar", value:"3", order:"1.11.5"},
 {name:"baz", value:"4", order:"2.6.2"},
 {name:"foo baz", value:"5", order:"1.3.10"},  
 {name:"foo baz", value:"5", order:"1.3"},   
 {name:"foo baz", value:"5", order:"2"}
];


arr.sort(function(item1, item2){
  var split1 = item1.order.split('.');
  var split2 = item2.order.split('.');
  var length = Math.min(split1.length, split2.length);
  for (var i=0; i<length; i++){
    if (+split1[i] < +split2[i])
      return -1;
    if (+split1[i] > +split2[i])
      return 1;
  }
  return split1.length - split2.length;

});

console.log(arr);

PS: Pure JS solution, not using Underscore.

Tibos
  • 27,507
  • 4
  • 50
  • 64
  • He wants to go n levels deep. The split 1, split 2 solution only goes 2 levels deep, right? – Zeke Nierenberg Oct 16 '13 at 14:27
  • @ZekeAlexandreNierenberg no, this will work no matter how long the sequences are. – Pointy Oct 16 '13 at 14:28
  • Out of curiousity here... What do the `+` signs do in the if statements?? Also, when you return -1 or 1 where is that returning too? And what does it do? – Kierchon Oct 16 '13 at 19:38
  • `Array.prototype.sort` receives as parameter a user-created comparison function that gets called with pairs of items from the array. For each pair the function should return 0 if they are equal, any positive number if the first is bigger and any negative number if the first is smaller (-1 and 1 work well because they are easy to spot). The unary `+` operator converts the value to a number. Without it, the values would be strings and the comparison would not work as expected. – Tibos Oct 17 '13 at 08:47
0

Check this out: How to compare software version number using js? (only number)

You're certainly going to have to split the order variable by "."

_.map([...],function(item) { item = item.split('.'); return item;});

At that point you have a new problem which is just sorting by multiple values. I think you'd perhaps group by the 0th value of each order array, then sort by the next.

Ultimately you'll probably end up with a recursive solution... I'll start thinking of one to edit in here.

Community
  • 1
  • 1
Zeke Nierenberg
  • 2,216
  • 1
  • 19
  • 30