Kirill Oleynik
Kirill Oleynik

Reputation: 13

How to change the JS Object keys sequence

I want to change the sequence of the keys of the object to the given one.(first male, then children followed by femal) There is an object:

const types = [
    {female: 100, male: 200, children: 150},
    {female: 100, male: 200, children: 150}
];

I get the object from the backend, where I need to change a sequence of the keys at the Front end of my app to male, children, female. I have never come across this problem, I tried several methods, didn't succeed. I will be extremely grateful for any help. Example output code for object fields:

{types && (
  <ul>_.map(Object.keys(types), key => (
    <li key={_.uniqueId(`${key}`)}>
      <span>{key, types[key]}</span>
    </li>
  </ul>
)}

100 female
200 male
150 children

The conclusion looks like this. It is necessary to change to:

200 male
150 children
100 female

Thank you very much!

Upvotes: 1

Views: 1472

Answers (4)

Thijs
Thijs

Reputation: 2351

I think it would be really bad idea to rely on the order of the object properties. Since it is an object coming from the backend using a Map is not going to solve your problems.

The easiest is probably to have an array with the property names in the order you want to display them. It gives you all the flexibility you will need and removes the reliances on order from an object.

const 
  data = [
    {female: 100, male: 200, children: 150},
    {female: 101, male: 201, children: 151}
  ],
  // This array controls the order the data item properties
  // will be added to the DOM.
  displayOrder = ['male', 'female', 'children'];

/**
 * Returns a string with the values of the provided item
 * wrapped in markup for TD elements.
 */ 
function createItemCells(item) {
  // Iterate of the properties to display in the table, this ensures
  // they'll be added in the desired order.
  return displayOrder.reduce((result, key) => {
    // Append a TD element for the current item property.
    return result + `<td>${item[key]}</td>`;
  }, '');
}

const
  // Iterate over the items in the data array and create a string
  // per item to show the data in the table.
  rows = data.reduce((output, item) => {  
    // Append a new row to the output.
    return output + `<tr>${ createItemCells(item) }</tr>`;
  }, '');
  
// Insert the generated rows into the table body in the DOM.
document.getElementById('output').innerHTML = rows;
<table>
  <thead>
    <tr>
      <th>Male</th>
      <th>Female</th>
      <th>Children</th>
    </tr>
  </thead>
  <tbody id="output"></tbody>
</table>

Upvotes: 0

Shilly
Shilly

Reputation: 8589

Situation: We need to display properties and values of an object inside a HTML list in a specific order.

Problems:

1) Property order is not 100% guaranteed, depends on engine implementation.

2) The data comes from the backend in JSON format, so we don't have a way to represent complex objects like a Map, since JSON does not know what maps are.

Solutions:

1) Write out the template fully:

const types = [
  {female: 100, male: 200, children: 150},
  {female: 100, male: 200, children: 150}
];
const html = [
  '<ul>',
  ...types.map( item => `<li>${ item.male } male<\/li><li>${ item.children } children<\/li><li>${ item.female } female<\/li>` ),
  '</ul>'
].join( '' );
console.log( html );

2) Provide an array containing the correct order to loop:

const types = [
  {female: 100, male: 200, children: 150},
  {female: 100, male: 200, children: 150}
];
const proper_order = [ 'male', 'children', 'female' ];
const create_html = function( data, order ) {
  return [
    '<ul>',
    ...types.map( item => order.map( property_name => `<li>${ item[ property_name ] } ${ property_name }<\/li>` ).join( '' )),
    '</ul>'
  ].join( '' );
};
const html = create_html( types, proper_order );
console.log( html );

Disclaimer: I'm using the array.join(''); method to create the html strings as an example only. A proper templating engine is adviced. The same logic is still applicable.

Upvotes: 0

Ankit Kumar Ojha
Ankit Kumar Ojha

Reputation: 2384

You might want to use Map, instead of objects to store the data from backend. JS Objects does not guarantee the order of keys (it's unordered). Even though JS engines implementation have ICs, which can make you delude that order never changes. I have quoted the ECMA Script 3rd edition below which will make it even more clearer.

4.3.3 Object: An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function. A function stored in a property of an object is called a method.

Since ECMAScript 2015, using the Map object could be an alternative. A Map shares some similarities with an Object and guarantees the keys order:

A Map iterates its elements in insertion order, whereas iteration order is not specified for Objects.

Upvotes: 0

Manasi
Manasi

Reputation: 765

You can use JSON.stringify(value[, replacer[, space]]) to format string and again convert in json

const types = [
    {female: 100, male: 200, children: 150},
    {female: 100, male: 200, children: 150}
];

var newjson = JSON.parse(JSON.stringify( types , ["male","female","children"]));
console.log(newjson);

Upvotes: 2

Related Questions