xims
xims

Reputation: 1608

Javascript: using date as array key doesn't work

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

Answers (2)

baao
baao

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

Liam Gray
Liam Gray

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

Related Questions