Display array of objects in particular order of heading names in the table

Viewed 146

I have an array of array of objects which is fetched from API. I want to display it keys of key-value pairs as headings/column names for a table. Currently the headings are coming in any random order.

But I want to display the fields mentioned in orderArray first then the rest of headings.

I have created an array of column names in the order I want

[destination_country_name, destination_country_id , primary_cost]

rest of the data can come in any order

var x = [
    {
        "destination_country_id":null,
        "primary_cost":"9.50",
        "region_id":null,
        "destination_country_name":"Everywhere Else",
        "name" : "xyz",
        "place":"abc"
    },
    {
        "destination_country_id":105,
        "primary_cost":"8.00",
        "region_id":null,
        "destination_country_name":"United Kingdom",
        "name" : "xyz1",
        "place":"abc1"
    },
    {
        "destination_country_id":209,
        "primary_cost":"9.50",
        "region_id":null,
        "destination_country_name":"United States",
        "name" : "xyz2",
        "place":"abc2"
    },
    {
        "destination_country_id":123,
        "primary_cost":"5.00",
        "region_id":null,
        "destination_country_name":"Ireland",
        "name" : "xyz3",
        "place":"abc3"
    }
]

Table with column names (in the below order only):

destination_country_name |destination_country_id |primary_cost

3 Answers

You can simply filter the remaining keys from element and than create a new array using initial and remaining, now during rendering you can use final for getting the names as in desired order

let initial = ['destination_country_name', 'destination_country_id', 'primary_cost']
var x = [{
  "destination_country_id": null,
  "primary_cost": "9.50",
  "region_id": null,
  "destination_country_name": "Everywhere Else",
  "name": "xyz",
  "place": "abc"
}]

let remaining = Object.keys(x[0]).filter( val => !initial.includes(val))

let final = [...initial, ...remaining]

console.log(final)

You may use Array.prototype.sort() with a comparator function. Here, I tested for least priority columns first, then for highest priority one. It is hard coded so not applicable to every situation, but it works.

I deliberately added more elements to the array (some with incorrect country ids) to ensure the items are ordered with correct priority.

var x = [{
    destination_country_id: null,
    primary_cost: "9.50",
    region_id: null,
    destination_country_name: "Everywhere Else",
    name: "xyz",
    place: "abc"
  },
  {
    destination_country_id: 105,
    primary_cost: "8.00",
    region_id: null,
    destination_country_name: "United Kingdom",
    name: "xyz1",
    place: "abc1"
  },
  {
    destination_country_id: 209,
    primary_cost: "9.50",
    region_id: null,
    destination_country_name: "United States",
    name: "xyz2",
    place: "abc2"
  },
  {
    destination_country_id: 124,
    primary_cost: "5.00",
    region_id: null,
    destination_country_name: "Ireland",
    name: "xyz3",
    place: "abc3"
  },
  {
    destination_country_id: 124,
    primary_cost: "3.00",
    region_id: null,
    destination_country_name: "Ireland",
    name: "xyz3",
    place: "abc3"
  },
  {
    destination_country_id: 123,
    primary_cost: "5.00",
    region_id: null,
    destination_country_name: "Ireland",
    name: "xyz3",
    place: "abc3"
  }
];

x.sort(function(a, b) {
  var return_value = 0;
  var destName_A = a.destination_country_name.toUpperCase();
  var destName_B = b.destination_country_name.toUpperCase();
  var destID_A = a.destination_country_id;
  var destID_B = b.destination_country_id;
  var cost_A = a.primary_cost;
  var cost_B = b.primary_cost;

  if (cost_A < cost_B) {
    return_value = -1;
  }
  if (cost_A > cost_B) {
    return_value = 1;
  }
  if (destID_A < destID_B) {
    return_value = -1;
  }
  if (destID_A > destID_B) {
    return_value = 1;
  }
  if (destName_A < destName_B) {
    return_value = -1;
  }
  if (destName_A > destName_B) {
    return_value = 1;
  }
  return return_value;
});

console.log(x);

I hope I understood you correctly.

Most of the time you will know the exact order of how data will be presented. Just keep it simple and clean.

...
<thead>
  <tr>
    <td>Destination Country Name</td>
    <td>Destination Country ID</td>
    <td>Primary Cost</td>
    ...
  </tr>
</thead>
<tbody>
    {x && !!x.length && x.map(item => 
      <tr key={...}>
        <td>{item.destination_country_name || ''}</td>
        <td>{item.destination_country_id || ''}</td>
        <td>{item.primary_cost || ''}</td>
        ...
      </tr>
    )}
</tbody>
...
Related