Reputation: 1855
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
Upvotes: 0
Views: 111
Reputation: 39250
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"));
Upvotes: 1