Sorting attributes inside JS Objects

Hi again :slight_smile:

I would like to know if there is a simple way to sort nested objects (inside an object) in alphabetical or numerical order?

I have the following object (exercise is from the youtube JS course on FCC)

var collection = {
 "2548" : {
  "album": "Slippery When Wet",
  "artist": "Bon Jovi",
  "tracks": [
   "Let It Rock",
   "You Give Love a Bad Name"
  ]
 },
 "2468": {
  "album": "1999",
  "artist": "Prince",
  "tracks": [
   "1999",
   "Little Red Corvette"
  ]
 },
 "1245": {
  "artist": "Robert Palmer",
  "tracks": []
 },
 "5439": {
  "album": "ABBA Gold"
 }
}

If I were to add some new objects and also attributes (tracks, albums etc.) using the code below, what happens is the console will print them out in the order they were added.

Is there an elegant way to sort this object?

 function updateRecords(id, prop, value) {
  if (value === "") { // this deletes an attribute if an emtpy string is used for value
   delete collection[id][prop];
  } 
  else if (prop === "tracks") { // this creates and/or adds to the array for tracks
   collection[id][prop] = collection[id][prop] || [];
   collection[id][prop].push(value); 
  } 
  else { // this adds a new attribute and entry 
   collection[id] = collection[id] || {}; // using the or operator to allow the function to create an empty object that we can populate
   collection[id][prop] = value;
  }
  return collection;
 }

Any help/feedback greatly appreciated!

D.W

Sure, it can be done:

const obj = {
  d: 4,
  c: 3,
  a: 1,
  e: 5,
  b: 2,
};

const objectSorter = GFG_Object =>
  Object.keys(GFG_Object)  
    .sort()
    .reduce((finalObject, key) => {  
      finalObject[key] = GFG_Object[key];  
      return finalObject;  
    }, {}); 

const sortedObj = objectSorter(obj);
console.log(sortedObj);
// {a: 1, b: 2, c: 3, d: 4, e: 5}

But why? One of the concepts of an object is that the order doesn’t matter. It used to be that the order of an object’s properties are never guaranteed, but I think that’s changed in newer JSs. But still, it’s not what objects are for.

what happens is the console will print them out in the order they were added.

But we don’t really care about the console. The user isn’t going to see the console. We care about the screen. And you should be in control of how it shows up on the screen, not just looping though the object properties. There are better ways to ensure the user sees them in the proper order.

2 Likes

I get why you might want this but no, this isn’t really the point of objects. They let you look up a value based on a key. What order they’re in doesn’t really matter. If you want an ordered collection, use an ordered collection (ie an array).

Technically you can do it by getting the keys Object.keys. That gives you the keys as an array, so you can sort the array, then create a new object, inserting the keys and their values one by one. Now you have an object in the order you want, and you can iterate using specific methods (Object.keys again, Object.getOwnPropertyNames, adding a symbol iterator property so you can use a for…of loop, or similar). But there’s no point, you can stop at the first step (get the keys in an array, sort them), because then you have the keys in the order you want and you can do whatever you want with them.

1 Like

Yeah, just to reemphasize, I agree 100% with what Dan is saying - you shouldn’t do it. I just did it as an intellectual exercise. But if you’re worried about the order of your object keys, then you’re using the wrong data structure.

1 Like

Thank you!

I’ve still got some learning to do to get my head around your solution, but it’s a direction!

And thanks for your explanation on the function of objects, I’ve been using the console to see what’s going on and haven’t gotten to the stage where I’m getting stuff to show up on the screen - it irked me to see the nested objects printed in every which way when they’re updated and so I wanted to know if there was a simpler way to move things around - as you mentioned this isn’t what objects are used for and so there isn’t an in built function :sweat_smile:

Thanks again for your help and advice!

D.W.

Hi Dan,

Thanks! I haven’t yet moved on to the part of the tutorial where I’m getting stuff to show up on a users interface, everything’s been on the console so far and I hate looking at disordered information so it was bugging me haha.

Cheers,

D.W

If it’s just for logging you might also be able to use JSON.stringify with a replacer array.

const obj = {
  d: 4,
  c: 3,
  a: 1,
  e: 5,
  b: 2,
};

const sortedObj = JSON.stringify(obj, Object.keys(obj).sort())
console.log(sortedObj);
// {"a":1,"b":2,"c":3,"d":4,"e":5}
2 Likes

Thank you! I’ll give this solution a try!