Extract Javascript data using map (), filter () and concatAll () functions

The result is almost correct, but I have a problem with the density of the nested boxart array.

Javascript data:

var movieLists = {
    name: "Instant Queue",
    videos : [
        {    
             "id": 70111470,
             "title": "Die Hard",
             "boxarts": [
                 {width: 150, height:200, url:"http://cdn-0.nflximg.com/images/2891/DieHard150.jpg"}, 
                 {width: 200, height:200, url:"http://cdn-0.nflximg.com/images/2891/DieHard200.jpg"}
             ],
            "url": "http://api.netflix.com/catalog/titles/movies/70111470",
            "rating": 4.0,
            "bookmark": [{ id:432534, time:65876586 }]
        },
        {
            "id": 654356453,
            "title": ....,
        }];

      

Expected results: (using only the functions .map()

, .filter()

, .concatAll()

, return statement id, title, Boxart: url No movies that have the image size of 150x200 Boxart

// [
//     {"id": 675465,"title": "Fracture","boxart":"http://cdn-0...." },
//     {"id": 65432445,"title": "The Chamber","boxart":"http://cdn-0...." },
//     {"id": 654356453,...}
// ];

      

Current output:

// [                                    //boxart value is an array
//     {"id": 675465,"title": "Fracture","boxart":["http://cdn-0...."]},
//     {"id": 65432445,"title": "The Chamber","boxart":["http://cdn-0...."]},
//     {"id": 654356453,...}
// ];

      

My solution :

return movieLists.map(function (category) {
   return category.videos.map(function (video) {
       return {
           id: video.id,
           title: video.title,
           boxart: video.boxarts.filter(function (boxartFeature) {
               return boxartFeature.width === 150 && boxartFeature.height === 200;
           })
               .map(function (boxartProp) {
               return boxartProp.url;
           })
       };
   });
 }).concatAll(); //Flattens nested array by 1 dimension (please see demo)

      

I know I need to apply a function .concatAll()

to remove the nested boxart array, but I cannot find the place where.

Please click here for a demo

+3


source to share


3 answers


You are very close. I recognize this as an observation exercise. Since you are looking at RxJS it is important that you DO NOT use indexing -> [0]. There is no concept of an index when dealing with Observables.

The trick for understanding this problem is to get close to what it does concatAll()

. It takes a two dimensional array and returns a flattened array.

[[1,2],[3,4]] --> [1,2,3,4]

With your current code, you are mapping boxartProp.url

to a nested array, but the rest of your properties are not. What you more or less right now [1,2,3,[4]]

. Want evenly nested array: [[1],[2],[3],[4]]

. The reason this is important is because it concatAll()

expects each member to be a subarray. If you haven't seen it yet, I recommend watching this video from Jafar Husain. He's awesome and implements concatAll

from scratch in video.

Your goal can be achieved with only a few minor changes.



return movieLists.map(function(category) {
    return category.videos.map(function(video) {
        return video.boxarts.filter(function(boxart) {
            return boxart.width === 150;
        }).map(function(boxart) {
            return {id: video.id, title: video.title, boxart: boxart.url};
        });
    }).concatAll();
}).concatAll();

      

Note that on the last map, instead of just displaying the boxart code, we are also transferring video data. This gives us a uniformly nested array that we need to run concatAll()

.

The reason we have to name twice concatAll()

is because your videos are nested into categories in your demo. The first call flattens the movies, and the second call flattens the categories.

Here is a modified jsbin for your review .

These are great work exercises. Good luck!

+3


source


map

returns an array. You store the result map

in a property boxart

.

If you don't want to store the array in boxart

, just store the first element (index 0

) of the array:



//...
.map(function (boxartProp) {
     return boxartProp.url;
})[0]

      

+1


source


Personally, I would use forEach () instead of map () and store the "correct" boxart in a local variable. Remember map () returns an array. ForEach is used instead, we can check each boxart and select the correct one. I like this solution because it is easier for someone else to read your code to understand what's going on. It also allows us to just use concatAll () neatly at the end of our chain.

return movieLists.map(function(category){                      

return  category.videos.map(function(vids){
    var correctBoxSize = "No Proper Box Size Found"; 

    vids.boxarts.forEach(function(boxes){
        if (boxes.width === 150 && boxes.height === 200)
            {correctBoxSize = boxes.url}
        });

    return {
            "id": vids.id,
            "title": vids.title,
            "boxart": correctBoxSize
           };
})
}).concatAll()

      

0


source







All Articles