rob.m
rob.m

Reputation: 10581

How to group using map?

I'm using the following to group some data:

const formatted = data.map(
    area => {
        return {
            "state": area["Province_State"],
            "lat": area["lat"],
            "long": area["long"],
            "data": Object.keys(area).reduce( (prev, next) => { 
            if(next === 'date' ) {
                // do something 
                prev[next] = removeTime( area[next]) 
            } else {
            prev[next]= area[next];                         
            }
            return prev;
            } , {})
        };
    }
);

But that is wrong for the format I need.

That produces a series of data like this:

{state: "Alabama", ID: "c6d6ee4b-89d3-4634-807d-340a2b35d6a4", long: -86, lat: 32, name: "Alabama", …}
ID: "c6d6ee4b-89d3-4634-807d-340a2b35d6a4"
data:
Active: "3470"
Confirmed: "3563"
Country_Region: "US"
Deaths: "93"
FIPS: "1"
Hospitalization_Rate: "12.26494527"
ISO3: "USA"
Incident_Rate: "75.98802021"
Mortality_Rate: "2.610159978"
People_Hospitalized: "437"
People_Tested: "21583"
Province_State: "Alabama"
Recovered: ""
Testing_Rate: "460.3001516"
UID: "84000001"
date: "2020-04-12"
lat: "32.3182"
long: "-86.9023"
__proto__: Object
lat: 32
long: -86
name: "Alabama"
state: "Alabama"

But since each State has more data for each date, I need all dates under data in order to have it like:

State: "Alabama"
ID: 2
Lat: 41.1533
Long: 20.1683
Province/State: ""
data: Array(109)
[0 … 99]
0: {date: "1/22/20", Confirmed: 0, Deaths: 0, Recovered: 0}
1: {date: "1/23/20", Confirmed: 0, Deaths: 0, Recovered: 0}
2: {date: "1/24/20", Confirmed: 0, Deaths: 0, Recovered: 0}

The code I'm using is not grouping ALL DATES under data but it's giving a series of separate objs

Upvotes: 4

Views: 152

Answers (1)

Danziger
Danziger

Reputation: 21171

It looks like you want to group by state rather than date, so you should actually be using Array.prototype.reduce() but the logic should be slightly different:

const data = [{
  'Province_State': 'CA',
  lat: 1.1,
  long: 1.1,
  date: '1/22/20 12:00',
  Confirmed: 0,
  Deaths: 0,
  Recovered: 0,
}, {
  'Province_State': 'CA',
  lat: 1.2,
  long: 1.2,
  date: '1/23/20 12:00',
  Confirmed: 1,
  Deaths: 1,
  Recovered: 1,
}, {
  'Province_State': 'LA',
  lat: 1.3,
  long: 1.3,
  date: '1/22/20 12:00',
  Confirmed: 2,
  Deaths: 2,
  Recovered: 2,
}];

const formatted = data.reduce((merged, entry) => {
  const {
    // These properties will show up only once per state:
    lat,
    long,
    Province_State: state,
    // Anything else is grouped inside the `data` field for this state's entry:
    ...rest
  } = entry;
  
  // You can modify the `date` field here:
  rest.date = rest.date.split(' ')[0];
  
  if (merged.hasOwnProperty(state)) {
    // If we already added an entry for this state, simply push the other properties to `data`:
    merged[state].data.push(rest);
  } else {
    // Otherwise, add the entry for this state:
    merged[state] = { state, lat, long, data: [rest] };
  }  
  
  return merged;  
}, { });

console.log(formatted);

If you want to use a conventional loop rather than Array.prototype.reduce():

const data = [{
  'Province_State': 'CA',
  lat: 1.1,
  long: 1.1,
  date: '1/22/20 12:00',
  Confirmed: 0,
  Deaths: 0,
  Recovered: 0,
}, {
  'Province_State': 'CA',
  lat: 1.2,
  long: 1.2,
  date: '1/23/20 12:00',
  Confirmed: 1,
  Deaths: 1,
  Recovered: 1,
}, {
  'Province_State': 'LA',
  lat: 1.3,
  long: 1.3,
  date: '1/22/20 12:00',
  Confirmed: 2,
  Deaths: 2,
  Recovered: 2,
}];

const merged = {};

for (let i = 0; i < data.length; ++i) {
  const {
    // These properties will show up only once per state:
    lat,
    long,
    Province_State: state,
    // Anything else is grouped inside the `data` field for this state's entry:
    ...rest
  } = data[i];
  
  // You can modify the `date` field here:
  rest.date = rest.date.split(' ')[0];
  
  if (merged.hasOwnProperty(state)) {
    // If we already added an entry for this state, simply push the other properties to `data`:
    merged[state].data.push(rest);
  } else {
    // Otherwise, add the entry for this state:
    merged[state] = { state, lat, long, data: [rest] };
  }  
}

console.log(merged);

Upvotes: 4

Related Questions