Reputation: 1608
I have a list of simple objects that include date and I need to group them by the date. Unfortunately it doesn't seem to work.
Here is simplified code:
games = [
{date:"3/5/17", name:"game 1, 3"},
{date:"3/5/17", name:"game 2, 3"},
{date:"4/5/17", name:"game 3, 4"},
{date:"4/5/17", name:"game 4, 4"},
{date:"4/5/17", name:"game 5, 4"},
{date:"5/5/17", name:"game 6, 5"},
{date:"5/5/17", name:"game 7, 5"},
]
let games_by_date = []
games.map( (i)=>{
if(!games_by_date[i['date']])
games_by_date[i['date']]=[];
games_by_date[i['date']].push(i);
} )
console.log(games_by_date) // shows [3/5/17: Array[2], 4/5/17: Array[3], 5/5/17: Array[2]], but shows it as Array[0]
console.log(games_by_date[0]) // undefined
console.log(games_by_date[1]) // undefined
games_by_date.map( (g)=>console.log(g) ) // doesn't even gets there
If I do the same but use a different column, it's working correctly.
games = [
{date:"3/5/17", day:"3", name:"game 1, 3"},
{date:"3/5/17", day:"3", name:"game 2, 3"},
{date:"4/5/17", day:"4", name:"game 3, 4"},
{date:"4/5/17", day:"4", name:"game 4, 4"},
{date:"4/5/17", day:"4", name:"game 5, 4"},
{date:"5/5/17", day:"5", name:"game 6, 5"},
{date:"5/5/17", day:"5", name:"game 7, 5"},
]
let games_by_date = []
games.map( (i)=>{
if(!games_by_date[i['date']])
games_by_date[i['date']]=[];
games_by_date[i['date']].push(i);
} )
console.log(games_by_date)
console.log(games_by_date[0])
console.log(games_by_date[1])
games_by_date.map( (g, d)=>console.log(d, g) )
console.log("--------------------")
let games_by_day = []
games.map( (i)=>{
if(!games_by_day[i['day']])
games_by_day[i['day']]=[];
games_by_day[i['day']].push(i);
} )
console.log(games_by_day)
console.log(games_by_day[0])
console.log(games_by_day[1])
games_by_day.map( (g, d)=>console.log(d, g) )
So it seems to happen because of the type of keys I'm using.
Did you come across it and how did you solved it? Thanks
Upvotes: 0
Views: 1535
Reputation: 73211
You can just use reduce to group by a key:
let games = [
{date:"3/5/17", name:"game 1, 3"},
{date:"3/5/17", name:"game 2, 3"},
{date:"4/5/17", name:"game 3, 4"},
{date:"4/5/17", name:"game 4, 4"},
{date:"4/5/17", name:"game 5, 4"},
{date:"5/5/17", name:"game 6, 5"},
{date:"5/5/17", name:"game 7, 5"},
];
let games_by_date = games.reduce((a,b) => {
a[b.date] = a[b.date] ? a[b.date].concat(b) : [b];
return a;
}, {});
console.log(games_by_date);
As the "dates" are just strings, there shouldn't be a problem with them.
As @Liam points out correctly, this will create an object rather than an array, for a full explanation on this see @Liam's answer.
Upvotes: 4
Reputation: 1129
Your games_by_date
array should be an object to be able to key by date. The day
key is automatically converted to an integer because they're in integer form, and can therefore be used as keys in the array. However, to use the date strings, you must change var games_by_date = {}
and it should work.
Note that you cannot .map
an object in regular JavaScript. However, you could loop over the keys with a for (i in games_by_date)
, or use lodash
to provide _.map(object, callback)
.
Upvotes: 2