Stewart Lynch
Stewart Lynch

Reputation: 995

Group and sort within an array of javascript objects

I have searched but I can't quite find a JavaScript/jQuery solution. I have an array of objects like this

  MLDS = [ 
    {"Group": "Red","Level": "Level 2"},
    {"Group": "Green","Level": "Level 1"},
    {"Group": "Red","Level": "Level 1"},
    {"Group": "Blue","Level": "Level 1"},
    {"Group": "Green","Level": "Level 2"},
    {"Group": "Yellow","Level": "Level 1"}
  ]

I want to be able to reorganize on Group and within the Group sort on Level to return another array of the objects in that new order so

  MLDS = [ 
    {"Group": "Red","Level": "Level 1"},
    {"Group": "Red","Level": "Level 2"},
    {"Group": "Green","Level": "Level 1"},
    {"Group": "Green","Level": "Level 2"},
    {"Group": "Blue","Level": "Level 1"},
    {"Group": "Yellow","Level": "Level 1"}
  ]

I need to be able to keep the Group in the order in which they first appear so I need, in this case to maintain the group order of Red, Green, Blue then yellow, but sort within those groups

Upvotes: 1

Views: 1198

Answers (1)

jshanley
jshanley

Reputation: 9128

First you need to iterate through the array once to set up an array that will contain the order of the groups, since that is to be maintained:

// this will hold the unique groups that have been found
var groupOrder = [];

// iterate through the array,
// when a new group is found, add it to the groupOrder
for (var i = 0; i < MLDS.length; i++) {
  // this checks that the current item's group is not yet in groupOrder
  // since an index of -1 means 'not found'
  if (groupOrder.indexOf(MLDS[i].Group) === -1) {
    // add this group to groupOrder
    groupOrder.push(MLDS[i].Group);
  }
}

Then you can use a sorting function that first sorts by what index the item's Group has in the groupOrder and then, if they have the same group, simply sorts by Level:

MLDS.sort(function(a, b) {
  if (groupOrder.indexOf(a.Group) < groupOrder.indexOf(b.Group)) {
    return -1;
  } else if (groupOrder.indexOf(a.Group) > groupOrder.indexOf(b.Group)) {
    return 1;
  } else if (a.Level < b.Level) {
    return -1;
  } else if (a.Level > b.Level) {
    return 1;
  } else {
    return 0;
  }
});

Upvotes: 3

Related Questions