0

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

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Note that he has to change his games_by_date to an object rather than array and this is a solid answer. (You could also rename res to games_by_date for clarity)
Pointed that out and linked to your answer for further explanation @LiamGray.
Thanks mate, +1 for the .reduce since it's a clean code style for what OP wants to do!
Thanks, that's great!
2

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).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.