Fabi
Fabi

Reputation: 973

loop through javascript object with customized order

I've been looking all over for a solution to my problem but can't seem to find any answers...so I'm not sure it's possible.

I have a javascript object with products info, so here's what it sort of looks like (note that it's already ordered the way I want it to be):

var prodType = {
  '7' : {'prodname' : 'Abel','prodtype' : 'Book', 'prodprice' : '49.00'},
  '212' : {'prodname' : 'Carl','prodtype' : 'Book', 'prodprice' : '49.00'},
  '211' : {'prodname' : 'Devon','prodtype' : 'Book', 'prodprice' : '49.00'},  
  '2' : {'prodname' : 'Sarah','prodtype' : 'Book', 'prodprice' : '49.00'},
  '10' : {'prodname' : 'Walter','prodtype' : 'Book', 'prodprice' : '49.00'}
}

And I loop through it to create a table for a certain plugin, so an example of how I get the info:

for(var val in prodType) {
   console.log('pid: '+val 
   + ' pname: '+prodType[val].prodname
   + ' pcategory: '+prodType[val].prodtype 
   + ' pprice: '+prodType[val].prodprice);
}

My problem is: I need to have it print ordered by prodname but keep the id as is - just like I'm providing it, since I'm using the ID for further DB handling. So, right now it prints:

pid: 2 pname: Sarah pcategory: Book pprice: 49.00
pid: 7 pname: Abel pcategory: Book pprice: 49.00
pid: 10 pname: Walter pcategory: Book pprice: 49.00
pid: 211 pname: Devon pcategory: Book pprice: 49.00
pid: 212 pname: Carl pcategory: Book pprice: 49.00

And I need it to look like this:

pid: 7 pname: Abel pcategory: Book pprice: 49.00
pid: 212 pname: Carl pcategory: Book pprice: 49.00
pid: 211 pname: Devon pcategory: Book pprice: 49.00
pid: 2 pname: Sarah pcategory: Book pprice: 49.00
pid: 10 pname: Walter pcategory: Book pprice: 49.00

Is is possible? If so, how? Thanks a bunch!

UPDATE

I've tried @go-oleg solution and turns out it won't work for my situation :( Here's what a sample of my real data looks like:

var prodType = {
  '211' : {'prodname' : '601A - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '49.00'},
  '212' : {'prodname' : '601B - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '49.00'},
  '214' : {'prodname' : '601C - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '49.00'},
  '224' : {'prodname' : '614A - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '0.00'},
  '225' : {'prodname' : '614C - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '0.00'},
  '231' : {'prodname' : '614D - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '0.00'},
  '226' : {'prodname' : '702B - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '49.00'},
  '227' : {'prodname' : '702C - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '49.00'},
  '217' : {'prodname' : 'COLL2 - Blahblah','prodtype' : 'Manual', 'prodprice' : '49.00'},
  '16' : {'prodname' : 'COLV - Blahblah','prodtype' : 'DVD', 'prodprice' : '100.00'},
  '119' : {'prodname' : 'UM - Blahblah','prodtype' : 'Manual', 'prodprice' : '29.00'},
  '235' : {'prodname' : 'WDS - Blahblah','prodtype' : 'Manual', 'prodprice' : '49.00'},
  '208' : {'prodname' : 'WTPO1 - Blahblah','prodtype' : 'Manual', 'prodprice' : '49.00'},
  '195' : {'prodname' : 'WTPO2 - Blahblah','prodtype' : 'Manual', 'prodprice' : '49.00'}
}

Upvotes: 1

Views: 131

Answers (2)

go-oleg
go-oleg

Reputation: 19480

Object properties in JavaScript aren't ordered, so ideally prodType would be an Array to begin with. If you can't change the format/structure of prodType, you can sort the keys and then look up the values associated with the key:

var prodType = {
  '7' : {'prodname' : 'Abel','prodtype' : 'Book', 'prodprice' : '49.00'},
  '212' : {'prodname' : 'Carl','prodtype' : 'Book', 'prodprice' : '49.00'},
  '211' : {'prodname' : 'Devon','prodtype' : 'Book', 'prodprice' : '49.00'},  
  '2' : {'prodname' : 'Sarah','prodtype' : 'Book', 'prodprice' : '49.00'},
  '10' : {'prodname' : 'Walter','prodtype' : 'Book', 'prodprice' : '49.00'}
};

//`sort` will sort by the "dictionary" order and it looks like you want the opposite, so use `reverse`
Object.keys(prodType).sort().reverse().forEach( function (key) {

   console.log('pid: '+key 
   + ' pname: '+prodType[key].prodname
   + ' pcategory: '+prodType[key].prodtype 
   + ' pprice: '+prodType[key].prodprice);

} );

UPDATE: As noted by @plalx, using a sort function to do the sort you want the first time around is faster than using the default sort and then reversing:

Object.keys(prodType).sort(function(a,b) {
  return a > b ? -1 : (a === b? 0 : 1);
}).forEach( function (key) {
   console.log('pid: '+key 
   + ' pname: '+prodType[key].prodname
   + ' pcategory: '+prodType[key].prodtype 
   + ' pprice: '+prodType[key].prodprice);
} );

Upvotes: 4

Naftali
Naftali

Reputation: 146320

Objects in javascript are not sorted but they are randomly placed in the order, it just so happens that your browser sorts the Object keys.

I would suggest adding the id to the individual objects and store then in an ordered array:

var prodType = [
  {'prodname' : 'Abel','prodtype' : 'Book', 'prodprice' : '49.00', 'id': 7},
  {'prodname' : 'Carl','prodtype' : 'Book', 'prodprice' : '49.00', 'id': 212},
  {'prodname' : 'Devon','prodtype' : 'Book', 'prodprice' : '49.00', 'id': 211},
  {'prodname' : 'Sarah','prodtype' : 'Book', 'prodprice' : '49.00', 'id': 2},
  {'prodname' : 'Walter','prodtype' : 'Book', 'prodprice' : '49.00', 'id': 10}
];

Then you can do:

prodType.forEach(function(el){
   console.log('pid: '+ el.id
   + ' pname: '+ el.prodname
   + ' pcategory: '+ el.prodtype 
   + ' pprice: '+ el.prodprice);
});

Upvotes: 2

Related Questions