0

Given the following data

[
  {
    "date": "2017-10-04",
    "games": [
      {
        "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-04T10:12:30+00:00",
        "sport": "hockey",
        "owner": "henry",
        "players": "10",
        "game_id": 4
      }
    ]
  },
  {
    "date": "2017-10-14",
    "games": [
      {
        "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-14T20:34:30+00:00",
        "sport": "soccer",
        "owner": "john",
        "players": "12",
        "game_id": 5
      }
    ]
  }
]

how do I filter out the objects so that I only show the hockey games played on that date. Essentially I need the same array of objects back, but the object should only be shown if the games key = sport: hockey

I know I can only run the filter method on arrays, but I can't figure out how to loop over the object inside of the array and return the whole object again. Any help would be greatly appreciated.

Blake
  • 553
  • 1
  • 4
  • 7
  • This might help too https://stackoverflow.com/questions/38375646/filtering-array-of-objects-with-arrays-based-on-nested-value – Andrew Lohr Oct 20 '17 at 23:22

3 Answers3

1

Try:

const filtered = yourArray.map(item => ({...item, games: item.games.filter(game => game.sport === 'hockey')})

// When run, this produces:
[
    {
        "date": "2017-10-04", 
        "games": [
            {
                "game_id": 1, 
                "notes": "Game was played", 
                "owner": "steve", 
                "players": "10", 
                "sport": "hockey", 
                "time": "2017-10-04T20:24:30+00:00"
            }, 
            {
                "game_id": 4, 
                "notes": "Game was played", 
                "owner": "henry", 
                "players": "10", 
                "sport": "hockey", 
                "time": "2017-10-04T10:12:30+00:00"
            }
        ]
    }, 
    {
        "date": "2017-10-14", 
        "games": [
            {
                "game_id": 3, 
                "notes": "Game was played", 
                "owner": "steve", 
                "players": "4", 
                "sport": "hockey", 
                "time": "2017-10-14T20:32:30+00:00"
            }
        ]
    }
]

Which I think is what you want.

CRice
  • 29,968
  • 4
  • 57
  • 70
  • Hi CRice, thanks for taking the time to answer me, but this didn't seems to work... I am trying to figure out basically how to get back the same array with the date and all the games, but the games should only show if they are = hockey. – Blake Oct 20 '17 at 22:41
  • I've updated my answer and provided the final object after the filter is complete. Look it over and if that's what you wanted, great, but otherwise let me know what data you are expecting to get back and I can modify this to produce it. – CRice Oct 20 '17 at 22:50
  • Hi CRice, I kept ketting an error when using the spread operator, so I used date: item.date, and that seemed to work. The only issue I am having is that this is also returning objects that don't have any hockey games (games array is empty), but since there were other games other than hockey on that date, I am getting back a date only with the games array empty... which is causing me to render empty components... just wondering if there is a way around this? My actual data is a lot larger than the sample i gave above, so there are some dates where there are no hockey games. – Blake Oct 20 '17 at 23:25
  • Hi CRice, This was basically the right answer, if anyone is wondering, in order to filter out the dates that didn't have any games, just run a for loop on the result and push only ones with length > 0 to a new array, and you should be good. – Blake Oct 21 '17 at 18:52
0

I think the following code should do the trick:

var x=[
{
"date": "2017-10-04",
"games": [
  {
    "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-04T10:12:30+00:00",
    "sport": "hockey",
    "owner": "henry",
    "players": "10",
    "game_id": 4
  }
]
},
{
"date": "2017-10-14",
"games": [
  {
    "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-14T20:34:30+00:00",
    "sport": "soccer",
    "owner": "john",
    "players": "12",
    "game_id": 5
  }
]
}]


function filterByDate (data, date){

   return data.filter(function(entry){
     return sameDay(new Date(entry.date), date)

   })
}

function filterBySport(data, sport){
   data.forEach(function(entry){
     entry.games=entry.games.filter(function(entry2){
        return entry2.sport===sport
     })
   })
   return data
 }

 function sameDay(date1, date2){ //helper function to check for date equality
   return date1.getFullYear()===date2.getFullYear() &&
          date1.getMonth()===date2.getMonth() &&
         date1.getDay()===date2.getDay() 
 }

 function myFilter(data, date, sportType){ // the final function you have to call
    return filterBySport(filterByDate(data, date), sportType)
 }

 console.log(myFilter(x, new Date("2017-10-04"), "hockey"))
user2887596
  • 641
  • 5
  • 15
0

Let's take an array :-

let students = [
  {"Name": "Priya","marks": [50, 60, 70, 80, 90]},
  {"Name": "Ankita","marks": [80, 90, 95]}
]

Now, I want to filter marks greater than or equal to 90, The code will look like this.

students.map((student) => {
  return {...student, 
          marks: student.marks.filter((mark) => mark >= 90)
         }
}) 
// Result will be [{"Name": "Priya", "marks": [90]}, {"Name": "Ankita","marks": [90,95]}]

Spread operator will expand student and then it will override the marks key with filtered marks value.

If you will not use spread operator,

students.map((student) => student.marks.filter((mark) => mark >= 90))
// Result will be [[90],[90]]

Then you will get only the filtered values and not the values on which you haven't applied the filter.

Nitesh Ranjan
  • 1,221
  • 1
  • 13
  • 13