0

I have the following object:

{
  name: 'Nome',
  key: 'Chave',
  created_by: 'Criado Por',
}

And the following array:

[
  {key: 'TEST1', name: 'Test 1', created_by: 'Guy'},
  {key: 'TEST2', name: 'Test 2', created_by: 'Guy'}
]

How can I sort each object key inside of the array to match the first object keys?

Desired result:

[
  {name: 'Test 1', key: 'TEST1', created_by: 'Guy'},
  {name: 'Test 2', key: 'TEST2', created_by: 'Guy'}
]
Mathias Hillmann
  • 435
  • 2
  • 12
  • Does this answer your question? [Does JavaScript guarantee object property order?](https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order) – Nisanth Reddy May 11 '21 at 20:39
  • By definition, object properties are not sorted. You can "fake" sort them by manually defining the properties in order, but it's not something that is guaranteed and is subject to change based on the implementation. If you truly need something sorted, you need to use an array – mhodges May 11 '21 at 20:39
  • What are you intending to do with the desired result? It usually doesn't matter what order the object keys are in, since you can just get the value by using `Object.key` – Brian Glaz May 11 '21 at 20:39
  • @BrianGlaz the first object is used ot make the header of a table (Name | Key | Created_by), so I need to order the array to match the order of the table header. – Mathias Hillmann May 11 '21 at 20:41
  • @NisanthReddy Sorry, that question didn't help me. – Mathias Hillmann May 11 '21 at 20:41
  • 1
    If that's the case, just make your "header object" an array of strings of the properties you want, then you can iterate over them and say `data[headerKey]` to get the corresponding value for each cell in that column – mhodges May 11 '21 at 20:43
  • @mhodges "*By definition, object properties are not sorted*" -> [Does ES6 introduce a well-defined order of enumeration for object properties?](https://stackoverflow.com/q/30076219) – VLAZ May 11 '21 at 20:48
  • @VLAZ I stand corrected - however I think the caveat in the top answer is still important: "*That doesn't change the fact that using property order for fundamental program logic probably isn't a good idea, since the order for non-integer-index properties depends on when the properties were created.*" – mhodges May 11 '21 at 20:53
  • @mhodges never claimed the opposite. Just pointed out that the definition is wrong. It *is* a bad idea to depend on the order because it can easily be disturbed by accident. Maybe you change something like `traverseObjectKeys(obj)` to `traverseObjectKeys(preprocess(obj))` and then the key order is then changed because of whatever `preprocess` does. Maybe it's even a library you cannot control. Worse, it might be fine now but then change 6 months later well after you've forgotten about it. So, there is an order but not a good idea to rely on it extensively. – VLAZ May 11 '21 at 20:57
  • @VLAZ yeah, wasn't arguing with you, just stating the caveat for other readers so they know that while support for predictable order of properties has recently been added, it's still not advised to rely on it for program logic. – mhodges May 11 '21 at 20:59

3 Answers3

1

Based on the comments, you need some table rendering, and need some order in the table columns. Including some simple translation of your column headers.

const data = [...];
const headers = {
  name: 'Nome',
  key: 'Chave',
  created_by: 'Criado Por'
}


for (var hk in headers) {
   // headers[hk]  will contain your translated header
}

for (var r in data) {
   // start your table-row here <tr>
   for (var hk in headers) {
      // data[r][hk] will contain the data of the column you requested
   }
   // end your table-row here </tr>
}

I'll leave the templating to you.

Leroy
  • 1,011
  • 8
  • 18
0

If what you need is to create a table from your values, maintain an array with the keys in the order you want.

Like this,

const order = ['name', 'key', 'created_by'];

Then while creating the table, loop over the above array and access your data. Something like this.

order.forEach(key => createCell(dataItem[key]))

The createCell function is something to make the <td> element and add them to your html

Nisanth Reddy
  • 3,483
  • 1
  • 4
  • 22
  • Seems that the OP doesn't know the keys ahead of time, so they will have to create the list of keys using a `const order = Object.keys(data[0])` – mhodges May 11 '21 at 20:48
  • But that would mean that even the order can't be guessed. Are you sure that the keys are not known before hand. How are the humanized strings even being generated ? – Nisanth Reddy May 11 '21 at 20:49
  • I don't think the particular order matters, it seems that the OP just wants to make sure they are getting the correct property for each cell in the table - I could be wrong though. – mhodges May 11 '21 at 20:51
0

You can use two loops, one to iterate over the table rows, and one to iterate over the table columns.

const headers = {
  name: 'Nome',
  key: 'Chave',
  created_by: 'Criado Por',
};

const rows = [
  {key: 'TEST1', name: 'Test 1', created_by: 'Guy'},
  {key: 'TEST2', name: 'Test 2', created_by: 'Guy'}
];

let output = '';

for(const item of rows) {
  output += '<tr>';
  for(const colName of Object.keys(headers)) {
    output += `<td>${item[colName]}</td>`;
   }
   output += '</tr>';
 }
 
 console.log(output);
Brian Glaz
  • 14,239
  • 4
  • 32
  • 53