1

I have an array of objects something like this

var itemArray = [
    {
        "name": "name1",
        "flag": true,
    },
    {
        "name": "name1",
        "flag": false,
    },
    {
        "name": "name2",
        "flag": false,
    },
    {
        "name": "name3",
        "flag": true,
    }        
];

I am already sorting this by the name key using the following:

var sortedItems = sortByKey(itemArray, "name");

function sortByKey(array, key) {
    return array.sort(function(a, b) {
        var x = a[key];
        var y = b[key];
        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
});

How do i also sort it by the flag key alphabetically so the false flags appear before the true flags? (I can use a string instead of boolean on the flag property if this makes it simpler)

To clarify, what I am looking for is an array which would be returned like this for example:

[
    { name: "name_a", flag: false },
    { name: "name_a", flag: true },
    { name: "name_b", flag: false },
    { name: "name_b", flag: true},
    { name: "name_c", flag: true},
    { name: "name_d", flag: false},
]
Greg
  • 187
  • 3
  • 15
  • 2
    The logic is simple: in your comparison function you first make your primary comparison, if this is *not equal*, you return the comparison result, else you do your secondary comparison and return its result. – deceze Jun 23 '16 at 13:45
  • Possible duplicate of [Javascript, how do you sort an array on multiple columns?](http://stackoverflow.com/questions/2784230/javascript-how-do-you-sort-an-array-on-multiple-columns) – Kld Jun 23 '16 at 13:52

3 Answers3

2

var sortedItems = sortByKey(itemArray, "name");

function sortByKey(array, key) {
    return array.sort(function(a, b) {
        if(a[key] == b[key]) {
          return (a['flag'] ? -1 : 1);
        } else {
          var x = a[key];
          var y = b[key];
          return x.localeCompare(y);
        }
});
Eduard Void
  • 2,646
  • 1
  • 13
  • 13
1
var sortedItems = sortByKey(itemArray, "name");

    function sortByKey(array, key) {
        return array.sort(function(a, b) {
            if(a['flag'] == f['flag']) {
              var x = a[key];
              var y = b[key];
              return ((x < y) ? -1 : ((x > y) ? 1 : 0));
            } else {
              return (a['flag'] ? -1 : 1);
            }
    });
Eduard Void
  • 2,646
  • 1
  • 13
  • 13
  • There's something wrong with this. It does not completely sort by name. Some are not in alphabetical order. – Greg Jun 23 '16 at 14:39
  • change ((x < y) ? -1 : ((x > y) ? 1 : 0)) to x.localeCompare(y) – Eduard Void Jun 23 '16 at 14:43
  • Still, this returns a list where all the items with a true flag are in alphabetical order by name, followed by all the items with false flags which are in alphabetical order by name. What I am looking for is a sorted list where the whole list is in alphabetical order by name, and also the flags are sorted alphabetically. e.g. "{ name: "name_a", flag: false }, { name: "name_a", flag: true}, {name: "name_b", flag: false }, {name: "name_b", flag: true}... – Greg Jun 23 '16 at 15:06
  • see my another answer. you can edit the ordering function anyway. the first you compare is the main sorting attribute and then follow to the comparation of other attributes – Eduard Void Jun 23 '16 at 15:13
1

You could use a proper callback, sort first by flag and if equal then by name.

var itemArray = [{ "name": "name1", "flag": true, }, { "name": "name1", "flag": false, }, { "name": "name2", "flag": false, }, { "name": "name3", "flag": true, }];

itemArray.sort(function (a, b) {
    return a.name.localeCompare(b.name) || a.flag - b.flag;
}),

console.log(itemArray);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • This appears to just sort by the flag key – Greg Jun 23 '16 at 14:32
  • why do you think so? – Nina Scholz Jun 23 '16 at 14:32
  • Actually, running the snippet only sorts by the flag, when I run it on my code it only sorts by the name, e.g. I now have a sorted array which contains the following data: name: "some name" flag: true, name: "some name" flag: false, name: "some name" flag: true – Greg Jun 23 '16 at 14:36