How can we custom sort JavaScript object keys?

2020-05-05 17:10发布

问题:

I am trying to custom sort a JavaScript object but not able to get how we can do this in a right way. Say I am having an object like

var test = {
  'yellow': [],
  'green': [],
  'red': [],
  'blue': []
}

And I have an array with values of : var arr = ['red', 'green', 'blue', 'yellow'];

So after sorting, I want to output in the order which is specified in array like

var test = {
  'red': [],
  'green': [],
  'blue': [],
  'yellow': []
}

But for some reason, I am not able to achieve that. What am trying to do here is loop and sort but it sorts in A-Z pattern and not in the order I've specified the array in. Also, you might ask that am not even using my array in the sort function but am not getting an exact way to achieve this.

var test = {
  'yellow': [],
  'green': [],
  'red': [],
  'blue': []
}

var keys = Object.keys(test);

console.log(keys.sort());  //["blue", "green", "red", "yellow"] which is not ordered nor it's an object

Any directions will he helpful.


Note: I am having this specific requirement because am using HandleBars with default {{#each}} block, but I want to loop the inner objects in that order. I can loop the objects in Handlebars and pass them to the template but than am not using the power of template engine. I want Handlebars to loop them or am I missing something? Is it fine if I loop the objects and pass the entire markup to handlebars template.

回答1:

JavaScript objects are hashes and therefore inherently un-ordered. You cannot make an object with properties in any given order. If you are receiving an ordering when you enumerate the keys, it is purely coincidental, or better said, an implementation detail of the JavaScript engine.

You'd have to use an array of objects to achieve something like what you want to do.

In other words, it is not possible with the data structure you have chosen.



回答2:

You could use Map()

A Map object iterates its elements in insertion order

var arr = ['red', 'green', 'blue', 'yellow'];

var map = new Map();

arr.forEach(function(val, index) {
  var obj = {};
  obj[val] = [];
  map.set(index, obj)
});

console.log(map)



回答3:

May be you could change this using JSON.stringify()

do like

var json = {     "name": "David",     "age" : 78,     "NoOfVisits" : 4   };
console.log(json);
//outputs - Object {name: "David", age: 78, NoOfVisits: 4}
//change order to NoOfVisits,age,name

var k = JSON.parse(JSON.stringify( json, ["NoOfVisits","age","name"] , 4));
console.log(k);
//outputs - Object {NoOfVisits: 4, age: 78, name: "David"} 

put the key order you want in an array and supply to the function. then parse the result back to json.