52

Given the following array of objects:

[
{
"notes": "Game was played",
"time": "2017-10-04T20:24:30+00:00",
"sport": "hockey",
"owner": "steve",
"players": "10",
"game_id": 1,
},
{
"notes": "Game was played",
"time": "2017-10-04T12:35:30+00:00",
"sport": "lacrosse",
"owner": "steve",
"players": "6",
"game_id": 2,
},
{
"notes": "Game was played",
"time": "2017-10-14T20:32:30+00:00",
"sport": "hockey",
"owner": "steve",
"players": "4",
"game_id": 3,
},
{
"notes": "Game was played",
"time": "2017-10-04T10:12:30+00:00",
"sport": "hockey",
"owner": "henry",
"players": "10",
"game_id": 4,
},
{
"notes": "Game was played",
"time": "2017-10-14T20:34:30+00:00",
"sport": "soccer",
"owner": "john",
"players": "12",
"game_id": 5,
}
]

I am trying to create a new array, that would create an object with each date(as a key) and any games played on that date listed under games(another key) in the same object.

The new array should look like:

[
{
date:'date string',
games:[array of games played on the date]
}, 
{
date: 'other date',
games:[games under the other date]
}
]...

Here is what I have done:

let t = this.state.data; (data above)
        let list = [];
        for (let i = 0; i < t.length; i++) {
            let dates = t[i].time.slice(0,10);

            if (!list[dates]) {
                list[dates] = [];
            }
            list[dates].push(t[i]);
        }

My version returns a array with the dates as the values, and then inside of those the games are listed, but i am trying to list them in the same object as different keys.

Any help or guidance would be greatly appreciated.

Blake
  • 553
  • 1
  • 4
  • 7
  • 1
    What have you tried so far? The solution is quite simple here. – Spencer Wieczorek Oct 18 '17 at 03:46
  • Hi Spencer, I'm not sure how to post code in comments, but I created an empty array, and ran a for loop to iterate over the first information. I sliced the original date to get the format in (yyyy-mm-dd) and then created another for loop to check if that date exists in the current empty array, and if it didn't, i would create a new key for that date, and then pass in any games into a game key. At first I got an infinte loop and my memory crashed, and then i kept overwriting my previous object. – Blake Oct 18 '17 at 03:50
  • You don't want to post your code in the comments, rather add it as an edit to the question. – Spencer Wieczorek Oct 18 '17 at 03:52
  • Do you mean you want to make the key the Date as in the day excluding the time? So there would be `2017-10-14` and `2017-10-04` as keys? – Spencer Wieczorek Oct 18 '17 at 04:04
  • Hi Spencer, I updated my post to show what I did... I got a similar result to the other answer posted, but what i am trying to do, is get an array, with an object for each date, which would have it's own key, and another key for the games played. so [{date: 'date string', games: [array of games]}] – Blake Oct 18 '17 at 04:07
  • @Blake check out my update – Austin Greco Oct 18 '17 at 04:10
  • @Blake What do you consider a `game`? The object item or just a subset of parameters such as `sport`? – Spencer Wieczorek Oct 18 '17 at 04:15
  • @SpencerWieczorek basically need the whole object listed in the 'games' array. – Blake Oct 18 '17 at 04:18

5 Answers5

134

Here's a solution using reduce. Split the time into a date string, and then set a key for each date. If the key exists push it onto the array:

Update added the array format version

const data = [
  {notes: 'Game was played', time: '2017-10-04T20:24:30+00:00', sport: 'hockey', owner: 'steve', players: '10', game_id: 1},
  { notes: 'Game was played', time: '2017-10-04T12:35:30+00:00', sport: 'lacrosse', owner: 'steve', players: '6', game_id: 2 },
  { notes: 'Game was played', time: '2017-10-14T20:32:30+00:00', sport: 'hockey', owner: 'steve', players: '4', game_id: 3 },
  { notes: 'Game was played', time: '2017-10-04T10:12:30+00:00', sport: 'hockey', owner: 'henry', players: '10', game_id: 4 },
  { notes: 'Game was played', time: '2017-10-14T20:34:30+00:00', sport: 'soccer', owner: 'john', players: '12', game_id: 5 }
];

// this gives an object with dates as keys
const groups = data.reduce((groups, game) => {
  const date = game.time.split('T')[0];
  if (!groups[date]) {
    groups[date] = [];
  }
  groups[date].push(game);
  return groups;
}, {});

// Edit: to add it in the array format instead
const groupArrays = Object.keys(groups).map((date) => {
  return {
    date,
    games: groups[date]
  };
});

console.log(groupArrays);
Austin Greco
  • 32,997
  • 6
  • 55
  • 59
  • Hi Austin, thank you for your answer. I was able to get a similar answer using a for loop, but what I need is for the the date to be its own key, and the games to be listed in an array as the value of another key (all within the same object). So {date: 'date', games: [...]} – Blake Oct 18 '17 at 04:01
  • @Blake got it, just saw the different format. I think the update I just added should give you what you're looking for. – Austin Greco Oct 18 '17 at 04:02
  • 1
    Thank you so much for your help Austin, this problem has been giving me a headache all day! – Blake Oct 18 '17 at 04:15
  • 2
    God, I was thinking this problem was gonna takes me several days lol, first searched on google, first link, your post, thank you so much ! That's perfect !!! – Mayoul Apr 18 '18 at 11:46
12

    let a =[{
      "notes": "Game was played",
      "time": "2017-10-04T20:24:30+00:00",
      "sport": "hockey",
      "owner": "steve",
      "players": "10",
      "game_id": 1,
      },
      {
      "notes": "Game was played",
      "time": "2017-10-04T12:35:30+00:00",
      "sport": "lacrosse",
      "owner": "steve",
      "players": "6",
      "game_id": 2,
      },
      {
      "notes": "Game was played",
      "time": "2017-10-14T20:32:30+00:00",
      "sport": "hockey",
      "owner": "steve",
      "players": "4",
      "game_id": 3,
      },
      {
      "notes": "Game was played",
      "time": "2017-10-04T10:12:30+00:00",
      "sport": "hockey",
      "owner": "henry",
      "players": "10",
      "game_id": 4,
      },
      {
      "notes": "Game was played",
      "time": "2017-10-14T20:34:30+00:00",
      "sport": "soccer",
      "owner": "john",
      "players": "12",
      "game_id": 5,
      }]

      let finalObj = {}
      a.forEach((games) => {
        const date = games.time.split('T')[0]
        if (finalObj[date]) {
          finalObj[date].push(games);
        } else {
          finalObj[date] = [games];
        }
      })
      console.log(finalObj)
Prasanna
  • 4,125
  • 18
  • 41
  • 1
    For typescript, you'll have to type the `finalObj`. Example: `let finalObj: {[key: string]: GameType} = {}` – user Aug 30 '22 at 21:22
5

Is this what you're looking for???

var data = [
    {
        notes: 'Game was played',
        time: '2017-10-04T20:24:30+00:00',
        sport: 'hockey',
        owner: 'steve',
        players: '10',
        game_id: 1
    },
    {
        notes: 'Game was played',
        time: '2017-10-04T12:35:30+00:00',
        sport: 'lacrosse',
        owner: 'steve',
        players: '6',
        game_id: 2
    },
    {
        notes: 'Game was played',
        time: '2017-10-14T20:32:30+00:00',
        sport: 'hockey',
        owner: 'steve',
        players: '4',
        game_id: 3
    },
    {
        notes: 'Game was played',
        time: '2017-10-04T10:12:30+00:00',
        sport: 'hockey',
        owner: 'henry',
        players: '10',
        game_id: 4
    },
    {
        notes: 'Game was played',
        time: '2017-10-14T20:34:30+00:00',
        sport: 'soccer',
        owner: 'john',
        players: '12',
        game_id: 5
    }
];

function extract() {
    var groups = {};

    data.forEach(function(val) {
        var date = val.time.split('T')[0];
        if (date in groups) {
            groups[date].push(val.sport);
        } else {
            groups[date] = new Array(val.sport);
        }
    });

    console.log(groups);
    return groups;
}

extract();
bobbyanne
  • 86
  • 4
  • Hi Bobby, thanks for taking the time to answer me. I was already getting it in a similar format. The format I needed (which Austin answered correctly above) was: [{date:'date string', games:[array of games for this date]}]. – Blake Oct 18 '17 at 04:16
  • Oh, I see ;D Happy Coding! – bobbyanne Oct 18 '17 at 04:21
4

With RxJS, In my case, using Angular

import { of } from "rxjs";
import { groupBy, map, mergeMap, reduce, toArray } from "rxjs/internal/operators";

const data = [
  {
    "notes": "Game was played",
    "time": "2017-10-04T20:24:30+00:00",
    "sport": "hockey",
    "owner": "steve",
    "players": "10",
    "game_id": 1,
  },
  {
    "notes": "Game was played",
    "time": "2017-10-04T12:35:30+00:00",
    "sport": "lacrosse",
    "owner": "steve",
    "players": "6",
    "game_id": 2,
  },
  {
    "notes": "Game was played",
    "time": "2017-10-14T20:32:30+00:00",
    "sport": "hockey",
    "owner": "steve",
    "players": "4",
    "game_id": 3,
  },
  {
    "notes": "Game was played",
    "time": "2017-10-04T10:12:30+00:00",
    "sport": "hockey",
    "owner": "henry",
    "players": "10",
    "game_id": 4,
  },
  {
    "notes": "Game was played",
    "time": "2017-10-14T20:34:30+00:00",
    "sport": "soccer",
    "owner": "john",
    "players": "12",
    "game_id": 5,
  }
];

of(...data).pipe(
  groupBy((p: any) => p.time.split('T')[0]),
  mergeMap(group$ =>
    group$.pipe(reduce((acc, cur) => [...acc, cur], [`${group$.key}`]))
  ),
  map(arr => ({ date: arr[0], games: arr.slice(1) })),
  toArray()
).subscribe(p => console.log(p));

Result:

enter image description here

Snowbases
  • 2,316
  • 2
  • 20
  • 26
0

Here is a simple solution using for loop

var cars = [
    { make: "kia", model: "k", year: "2012" },
    { make: "audi", model: "a", year: "2012" },
    { make: "audi", model: "a", year: "2013" },
    { make: "ford", model: "f", year: "2012" },
    { make: "ford", model: "f", year: "2015" },
    { make: "ford", model: "f", year: "2015" },
  ];

 let sorted = {}
for (let i =0; i < cars.length; i++ ){
    let make = cars[i].make
    if(sorted[make]== null) sorted[make] = []
    // console.log(sorted);
    sorted[make].push(cars[i])
 }
 console.log(sorted)
adam
  • 49
  • 2
  • 6