2015-07-31 2 views
3

Результат почти правильный, но у меня возникают проблемы с выравниванием вложенного массива boxart. ДанныеИзвлечь данные Javascript, используя функции map(), filter() и concatAll()

Javascript:

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": ...., 
     }]; 

Ожидаемый результат: (с использованием только функции .map(), .filter(), .concatAll(), вернуть идентификатор, название, Boxart: URL фильмов, которые имеют размеры Boxart изображения 150x200

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

Токовый выход:

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

мое решение:

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) 

Я знаю, что нужно применить функцию .concatAll() удалить вложенную массив Boxart, но я не могу найти место, где.

Пожалуйста, нажмите here for demo

+0

«У меня есть данные JSON» - это JavaScript, а не JSON. – Quentin

ответ

3

Вы очень близки. Я признаю это упражнением для наблюдений. Поскольку вы изучаете RxJS, важно, чтобы вы делали NOT индексирование использования -> [0]. Нет понятия индекса при работе с Observables.

Уловка для понимания этой проблемы заключается в том, чтобы присмотреться к тому, что делает concatAll(). Он принимает двумерный массив и возвращает сплющенный массив.

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

С текущим кодом, вы картографирование boxartProp.url в вложенный массив, но остальная часть ваших свойств не являются. Сейчас у вас более или менее есть: [1,2,3,[4]]. Вы хотите иметь равномерно вложенный массив: [[1],[2],[3],[4]]. Причина, по которой это важно, состоит в том, что concatAll() ожидает, что каждый член будет подмассивом. Если вы еще этого не видели, я рекомендую посмотреть this video от Jafar Husain. Он изумительный и реализует concatAll с нуля в видео.

Ваша цель может быть выполнена всего несколькими незначительными изменениями.

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(); 

Обратите внимание, как в последней карте, а не только отображение Boxart URL, мы передаем видеоданные как хорошо. Это дает нам равномерно вложенный массив, который нам нужно запустить concatAll().

Причина, по которой мы должны позвонить concatAll(), состоит в том, что ваши видеоролики вложены в категории в вашей демонстрации. Первый звонок сглаживает фильмы, а второй вызов выравнивает категории.

Here is the modified jsbin for your review.

Это отличные упражнения для работы. Удачи!

+0

Лучшая версия 'concatAll' https://jsbin.com/nipecivako/edit?js,console. :) – lokeshjain2008

1

map возвращает массив. Вы сохраняете результат map в собственности boxart.

Если вы не хотите, чтобы сохранить массив в boxart, просто хранить первый элемент (индекс 0) массива вместо:

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

Лично я использовал forEach() вместо map() и сохранил «правильный» boxart в локальной переменной. Помните, что map() возвращает массив. Вместо этого используется forEach, мы можем проверить каждый боксарт и выбрать правильный. Мне нравится это решение, потому что кому-то еще легче читать ваш код, чтобы понять, что происходит. Это также позволяет нам просто использовать concatAll() аккуратно в конце нашей цепочки.

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() 
Смежные вопросы