0

I have the following array of objects which orders the list. The problem is that the ordering is wrong because the OrderId property is not unique across all headings. The OrderId starts from 1 for each heading, hence the problem. Please help! Many thanks

// Class
var Item = function(orderId, forename, surname, heading) {
 this.OrderId = orderId;
 this.Forename = forename; 
 this.Surname = surname;
 this.Heading = heading;
};
// Creation of objects
var obj1 = new Item(1, "James", "Smith", "Heading1");
var obj2 = new Item(2, "Tracey", "Janes", "heading1");
var obj3 = new Item(3, "Sarah", "Cann", "Heading1");
var obj4 = new Item(1, "Matt", "Bars", "Heading2");
var obj4 = new Item(2, "Alex", "Magi", "Heading2");
// Add to array
tempArray.push(obj1);
tempArray.push(obj2);
tempArray.push(obj3);
tempArray.push(obj4);
// Sort array
tempArray.sort(function(a, b) {
 var a1 = a.OrderId, b1 = b.OrderId;
 if (a1 == b1) return 0;
 return a1 > b1 ? 1 : -1;
});
// Render array to screen - order by OrderId
for(var i = 0; i < tempArray.length; i++) {
 console.log(tempArray[i].Heading);
 console.log(tempArray[i].Forename + " " + tempArray[i].Surname);
}

The output I need:

Heading 1
 James Smith
 Tracey Janes
 Sarah Cann
Heading 2
 Matt Bars
 Alex Magi

Because the OrderId is not unique across I get the following issue

Heading 1
 James Smith
 Matt Bars
 Alex Magi
 Tracey Janes
 Sarah Cann
Heading 2
Liam
30k28 gold badges140 silver badges204 bronze badges
asked Jul 5, 2013 at 12:38
5
  • stackoverflow.com/questions/16164078/… Commented Jul 5, 2013 at 12:45
  • 2
    Do you understand what jQuery is? Commented Jul 5, 2013 at 12:50
  • You code seems to sort it correctly already: jsfiddle.net/C7WCU Commented Jul 5, 2013 at 12:50
  • 1
    I don't see any use of jQuery here...this is your whole question? Commented Jul 5, 2013 at 12:53
  • Removed jQuery tag as it's not relevant Commented Jul 5, 2013 at 13:34

1 Answer 1

1

If you want to default order by id then you can add toString method to your Object and return the id as string as this is used by .sort:

var Item = function(orderId, forename, surname, heading) {
 this.OrderId = orderId;
 this.Forename = forename; 
 this.Surname = surname;
 this.Heading = heading;
};
Item.prototype.toString=function(){
 return this.OrderId+"";
};
// create a bunch of Items
tmpArray.sort();// done, it's sorted by id now

If you want to sort it on certain key(s) then you can pass a sort function to tmpArray.sort

function sortItems(arr,keys){
 var len=keys.length;
 arr.sort(function(a,b){
 var i=0;
 while(a[keys[i]]===b[keys[i]]&&i<len){
 i++;
 }
 return i===len?0:(a[keys[i]]>b[keys[i]])?1:-1;
 }
};
// sort by Surname then by Forename (if 2 items have same Surname)
sortItems(tmpArray,["Surname", "Forename"]);

Looking at your question again I see it's not the sorting that is the problem but the grouping. here is a function that would implement grouping for you.

var Item = function(orderId, forename, surname, heading) {
 this.OrderId = orderId;
 this.Forename = forename; 
 this.Surname = surname;
 this.Heading = heading;
};
// Creation of objects
var obj1 = new Item(1, "James", "Smith", "Heading1");
var obj2 = new Item(2, "Tracey", "Janes", "Heading1");
var obj3 = new Item(3, "Sarah", "Cann", "Heading1");
var obj4 = new Item(1, "Matt", "Bars", "Heading2");
var obj5 = new Item(2, "Alex", "Magi", "Heading2");
var tempArray=[];
tempArray.push(obj1);
tempArray.push(obj2);
tempArray.push(obj3);
tempArray.push(obj4);
tempArray.push(obj5);
function sortItems(arr,keys){
 var len=keys.length;
 arr.sort(function(a,b){
 var i=0;
 while(a[keys[i]]===b[keys[i]]&&i<len){
 i++;
 }
 return i===len?0:(a[keys[i]]>b[keys[i]])?1:-1;
 });
};
// sort on Heading
sortItems(tempArray,["Heading","Forename","Surname"]);
function groupBy(arr,key){
 var i=0,ret={};
 for(i=0;i<arr.length;i++){
 if(!ret[arr[i][key]]){
 ret[arr[i][key]]=[];
 }
 ret[arr[i][key]].push(arr[i]);
 }
 return ret;
};
var grouped=groupBy(tempArray,"Heading");
var key="",i =0,ret=[];
// If any code in your page adds to Object.prototype then this breaks
// like Object.prototype.mySmartFuncion since mySmartFunciton will show
// up as key in for key in anyObject
for(key in grouped){
 ret.push(grouped[key][0].Heading);
 for(i=0;i<grouped[key].length;i++){
 ret.push("\t"+grouped[key][i].Forename + grouped[key][i].Surname);
 }
}
console.log(ret.join("\n"));
answered Jul 5, 2013 at 12:48
4
  • this 'works' - but unfortunately it causes me a problem because it orders the headings in alphabetical order which is not the order I need it in. Commented Jul 5, 2013 at 12:59
  • @JamesRadford Fixing your problem requires both sorting and grouping, added code to my answer to address the grouping. Commented Jul 5, 2013 at 13:16
  • this hasn't made a difference(?) Commented Jul 5, 2013 at 13:26
  • @JamesRadford Removed some typos and should output grouped by Header property sorted on firstname then lastname. Commented Jul 5, 2013 at 13:32

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.