Home > Back-end >  reconstruct an array of objects from another object array
reconstruct an array of objects from another object array

Time:10-21

Currently, I have an array in Javascript named locations, described below:

let locations = [
    {
      "id": "1",
      "city": "Kermit",
      "state": "TX",
    },
    {
      "id": "2",
      "city": "Bloomington",
      "state": "MN",
    },
    {
      "id": "3",
      "city": "Pauls Valley",
      "state": "OK",
    },
    {
      "id": "4",
      "city": "Colville",
      "state": "WA",
    },
    {
    "id": "5",
    "city": "Jacksboro",
    "state": "TX",
    },
    {
      "id": "6",
      "city": "Shallowater",
      "state": "TX"    
    }
  ]

using Javascript, I need to create another array from this array by filtering out the cities with the same states as a single array within the locations array. required output:

locations = [
    TX:[{
      "id": "1",
      "city": "Kermit",
      "state": "TX",
    },
    {
    "id": "5",
    "city": "Jacksboro",
    "state": "TX",
    },
    {
      "id": "6",
      "city": "Shallowater",
      "state": "TX"    
    }
   ],
   MN:[
    {
      "id": "2",
      "city": "Bloomington",
      "state": "MN",
    },
   ],
    OK:[
    {
      "id": "3",
      "city": "Pauls Valley",
      "state": "OK",
    },
   ],
   WA:[
    {
      "id": "4",
      "city": "Colville",
      "state": "WA",
    },
   ]
  ]

Also, I need this array sorted in alphabetical order. If some one could give me a good approach to solve this scenario, it would be a great help.

CodePudding user response:

const locations = [
  { "id": "1", "city": "Kermit",       "state": "TX" },
  { "id": "2", "city": "Bloomington",  "state": "MN" },
  { "id": "3", "city": "Pauls Valley", "state": "OK" },
  { "id": "4", "city": "Colville",     "state": "WA" },
  { "id": "5", "city": "Jacksboro",    "state": "TX" },
  { "id": "6", "city": "Shallowater",  "state": "TX" }
];

const byState = {};

[...locations].sort((a,b) =>
  a.state.localeCompare(b.state) || a.city.localeCompare(b.city)
).forEach(i => (byState[i.state]??=[]).push(i));

console.log(byState);

CodePudding user response:

You can reduce the locations into groups by state. Once you have achieved that, you can convert the object key-value pairs to entries, sort them, and then convert them back into an object.

const locations = [
  { "id": "1", "city": "Kermit",       "state": "TX" },
  { "id": "2", "city": "Bloomington",  "state": "MN" },
  { "id": "3", "city": "Pauls Valley", "state": "OK" },
  { "id": "4", "city": "Colville",     "state": "WA" },
  { "id": "5", "city": "Jacksboro",    "state": "TX" },
  { "id": "6", "city": "Shallowater",  "state": "TX" }
];

const sortObjectKeys = (obj) =>
  Object.fromEntries(Object.entries(obj).sort(([a], [b]) => a.localeCompare(b)));

const groupedByState = sortObjectKeys(
  locations.reduce((acc, location) => ({
    ...acc,
    [location.state]: [...(acc[location.state] ?? []), {
      ...location
    }]
  }), {}));

console.log(groupedByState);
.as-console-wrapper { top: 0; max-height: 100% !important; }

If you want to forgo sorting, just reduce the data:

const locations = [
  { "id": "1", "city": "Kermit",       "state": "TX" },
  { "id": "2", "city": "Bloomington",  "state": "MN" },
  { "id": "3", "city": "Pauls Valley", "state": "OK" },
  { "id": "4", "city": "Colville",     "state": "WA" },
  { "id": "5", "city": "Jacksboro",    "state": "TX" },
  { "id": "6", "city": "Shallowater",  "state": "TX" }
];

const groupedByState = 
  locations.reduce((acc, { state, ...location }) => ({
    ...acc,
    [state]: [...(acc[state] ?? []), { ...location, state }]
  }), {});

console.log(groupedByState);
.as-console-wrapper { top: 0; max-height: 100% !important; }

  • Related