0

I currently have data that looks like this:

[{
    "id": 1,
    "name": "Canada",
    "checked": true,
    "vacationSpots": [{
        "id": 1,
        "name": "Toronto",
        "checked":false,
        "activities": [{
            "id": 1,
            "checked": false,
            "name": "Niagara Falls"
        }]
    }, {
        "id": 2,
        "name": "France",
        "checked":true,
        "activities": [{
            "id": 2,
            "checked":true,
            "name": "Eiffel tower"
        }]
    }]
}, {
    "id": 2,
    "name": "US",
    "checked": true,
    "vacationSpots": [{
        "id": 3,
        "name": "California",
        "checked": true,
        "activities": [{
            "id": 3,
            "name": "Surfing",
            "checked":false
        }]
    }]
}]

I'm gathering the activities id's from activities which have checked set to true.

so the result looks something like this:

2

While I can get this, I have to go through 3 levels before I can access activities

  for (i = 0; i < country.length; i++){
    country = allAreas[i];
  ....
    for (j = 0; j < country.vacationSpots.length; j++){
  ....
        for (k = 0; k < vacationSpots.activities.length; k++){

(Search through country, then vacationSpots, then activities. Is there a way to filter this without traversing through each level? Is there a way to do this with Lodash?

lost9123193
  • 10,460
  • 26
  • 73
  • 113
  • Don't see a way to do this without using nested iterators. What does your current code look like? – Phil Sep 02 '16 at 01:29
  • @Phil The way I'm currently traversing through this is via three for loops, 1 to loop over each country, another to loop over the vacationSpots in each country and a final 1 to loop over the activities in each vacationspot. – lost9123193 Sep 02 '16 at 02:06
  • I updated my code with a bit of my for loop snippet – lost9123193 Sep 02 '16 at 02:12
  • 1
    If you want to go through an array to find something, you have to go through the array. If you want to go through a nested array to find something, you have to go through the nested array--one way or another. –  Sep 02 '16 at 03:38
  • can `activities` contain more than one element? –  Sep 02 '16 at 03:54
  • Your code is invalid. Missing comma after a couple of `checked` properties. –  Sep 02 '16 at 04:00
  • @torazaburo yes activities can contain more than 1 element. – lost9123193 Sep 02 '16 at 04:07
  • Is it meant to be `vacationSpots` instead of `vactionSpots`? – Phil Sep 02 '16 at 04:27
  • @Phil My bad! It's vacationSpots, – lost9123193 Sep 02 '16 at 04:31

1 Answers1

2

In the interest of providing an array of unique activity IDs for checked activities across your entire data set, assuming that any particular activity could potentially show up in more than one country / vacation spot, something like this should suffice

let data = [{"id":1,"name":"Canada","checked":true,"vacationSpots":[{"id":1,"name":"Toronto","checked":false,"activities":[{"id":1,"checked":false,"name":"Niagara Falls"}]},{"id":2,"name":"France","checked":true,"activities":[{"id":2,"checked":true,"name":"Eiffel tower"}]}]},{"id":2,"name":"US","checked":true,"vacationSpots":[{"id":3,"name":"California","checked":true,"activities":[{"id":3,"name":"Surfing","checked":false}]}]}];

let activityMap = data.reduce((map, country) => {
    country.vacationSpots.forEach(vs => {
        vs.activities.forEach(activity => {
            if (activity.checked) {
                map[activity.id] = true;
            }
        });
    });
    return map;
}, Object.create(null));

let activities = Object.keys(activityMap).map(Number);
console.log(activities);
Phil
  • 157,677
  • 23
  • 242
  • 245