0

У меня есть следующий код на controller.js и gallery.htmlУгловая Уплотненный массив фильтрации весь объект

\t .controller ('VideoGalleryController', ['$scope', 'videogalleryFactory', function($scope, videogalleryFactory){ \t \t \t \t 
 
\t  //Values of genre searchbox 
 
\t \t $scope.genreOptions = [ 
 
\t   'Action', 
 
\t   'Adventure', 
 
\t   'Comedy', 
 
\t   'Crime', 
 
\t   'Drama', 
 
\t   'Historical', 
 
\t   'Horror', 
 
\t   'Mistery', 
 
\t   'Musical', 
 
\t   'Romance', 
 
\t   'Science Fiction', 
 
\t   'Thriller', 
 
\t   'Western' 
 
\t   ]; 
 
\t \t 
 
\t \t //Get dishes from db_movies.json 
 
\t \t videogalleryFactory.getMovies().query(
 
       function(response) { 
 
        $scope.movies = response; 
 
        //Displays nested genres 
 
        angular.forEach($scope.movies, function(item){ 
 
        \t console.log(item.genre); 
 
        }) 
 
       }, 
 
       function(response) { 
 
        $scope.message = "Error: "+response.status + " " + response.statusText; 
 
       }); \t \t \t \t \t 
 
\t }])
\t <div class="row row-content-cards"> 
 
\t \t <div class="col-xs-12 col-sm-9"> 
 
\t \t \t <!-- Title filter --> 
 
\t \t \t <div class="form-group"> 
 
\t \t \t \t <label class="col-sm-3 control-label label-title" for="search">Search movie:</label> 
 
\t \t \t \t <div class="col-sm-9"> 
 
\t \t \t \t \t <input type="text" class="form-control" placeholder="Search movie" ng-model="moviesfilter.title"> 
 
\t \t \t \t </div> 
 
\t \t \t </div> 
 
\t \t \t <!-- Genre filter --> 
 
\t \t \t <div class="form-group"> 
 
\t \t \t \t <label for="genre" class="col-sm-3 control-label">Search genre</label> \t \t \t       
 
\t \t \t \t <div class="col-sm-9"> 
 
\t \t \t \t \t <select class="form-control" 
 
\t \t \t \t \t \t \t multiple 
 
\t \t \t \t \t \t \t chosen \t \t \t 
 
\t \t \t \t \t \t \t id="genre" 
 
\t \t \t \t \t \t \t name="genre" \t \t \t \t \t \t \t 
 
\t \t \t \t \t \t \t data-placeholder="Search genres" 
 
\t \t \t \t \t \t \t no-results-text="'Could not find that genre'" 
 
\t \t \t \t \t \t \t ng-model="???" 
 
\t \t \t \t \t \t \t ng-options="s for s in genreOptions"> 
 
\t \t \t \t \t \t \t <option value=""></option> 
 
\t \t \t \t \t </select> \t \t \t \t 
 
\t \t \t \t </div> \t \t \t 
 
\t \t \t </div> 
 
\t \t </div> 
 
\t </div> 
 
    
 
\t <div class="container-fluid cards-row"> 
 
\t \t <div calss="hover-effect"> 
 
\t \t \t <div class="col-sm-6 col-md-4" ng-repeat="movie in movies | filter:moviesfilter as filtText"> 
 
\t \t \t \t <div class="hover-div"> 
 
\t \t  \t \t <div class="thumbnail"> 
 
\t \t  \t \t \t <img ng-src={{movie.cover}} alt="{{movie.alt}}" > 
 
\t \t  \t \t \t <div class="caption"> 
 
\t \t   \t \t \t <h3>{{movie.title}}</h3> 
 
\t \t   \t \t \t <span class="badge-space badge" ng-repeat="genre in movie.genre | filter:genre"><strong>{{genre}} </strong></span> 
 
\t \t   \t \t \t <div class="titlewraptext"> 
 
\t \t   \t \t \t \t {{movie.plot}} 
 
\t \t   \t \t \t </div> 
 
\t \t   \t \t \t <p><a href="#" class="btn btn-primary" role="button">Details</a></p> 
 
\t \t  \t \t \t </div> 
 
\t \t  \t \t </div> 
 
\t \t \t \t </div> 
 
\t \t \t </div> 
 
\t \t </div> \t 
 
\t </div> 
 
\t <p ng-if="filtText.length === 0"> 
 
\t  <strong>No results found...</strong> 
 
    <p> 
 
</div>

Я хочу, чтобы на Filter by genre screenshot раз значение выбирается весь фильм на фильтровать. В этом примере должны отображаться только «La momia» и «Gladiator».

Структура JSON файл следующий:

{ 
    "movies": [ 
    { 
     "title": "La momia", 
     "releasedate": "1998-12-31T23:00:00.000Z", 
     "length": 125, 
     "genre": [ 
     "Adventure" 
     ], 
     "plot": "Durante una batalla en Egipto, el legionario Rick O'Connell y un compañero descubren las ruinas de Hamunaptra, la ciudad de los muertos. Algún tiempo después vuelven al mismo lugar con una egiptóloga y su hermano. Allí coinciden con un grupo de estadounidenses, deseosos de correr aventuras, que acabarán provocando la resurrección de la momia de un diabólico sacerdote egipcio que intenta desesperadamente recuperar a su amada.", 
     "cast": "Brendan Fraser, Rachel Weisz, John Hannah, Arnold Vosloo, Jonathan Hyde, Oded Fehr, Kevin J. O'Connor, Stephen Dunham, Aharon Ipalé, Tuc Watkins, Omid Djalili, Erick Avari, Carl Chase, Corey Johnson, Bernard Fox, Patricia Velasquez, Ray Donn", 
     "cover": "img/film_covers/lamomia.png", 
     "downloaddate": "2000-02-04T23:00:00.000Z", 
     "alt": "La momia", 
     "id": 1 
    }, 
    { 
     "title": "Los juegos del hambre", 
     "releasedate": "2011-12-31T23:00:00.000Z", 
     "length": 143, 
     "plot": "Lo que en el pasado fueron los Estados Unidos, ahora es una nación llamada Panem; un imponente Capitolio ejerce un control riguroso sobre los 12 distritos que lo rodean y que están aislados entre sí. Cada distrito se ve obligado a enviar anualmente un chico y una chica entre los doce y los dieciocho años para que participen en los Hunger Games, unos juegos que son transmitidos en directo por la televisión. Se trata de una lucha a muerte, en la que sólo puede haber un superviviente. Katniss Everdeen, una joven de dieciséis años, decide sustituir a su hermana en los juegos; pero para ella, que ya ha visto la muerte de cerca, la lucha por la supervivencia es su segunda naturaleza.", 
     "cover": "img/film_covers/losjuegosdelhambre.jpg", 
     "cast": "Jennifer Lawrence, Josh Hutcherson, Elizabeth Banks, Woody Harrelson, Donald Sutherland, Stanley Tucci, Liam Hemsworth, Toby Jones, Lenny Kravitz, Wes Bentley, Paula Malcomson, Isabelle Fuhrman, Sandra Ellis Lafferty, Paula Malcomson, Kimiko Gelman, Nelson Ascencio, Brooke Bundy, Amandla Stenberg, Dayo Okeniyi, Leven Rambin, Jack Quaid, Latarsha Rose, Alexander Ludwig, Jacqueline Emerson", 
     "downloaddate": null, 
     "alt": "Los juegos del hambre", 
     "genre": [ 
     "Action", 
     "Drama", 
     "Science Fiction" 
     ], 
     "id": 2 
    }, 
    { 
     "title": "Gladiator", 
     "releasedate": "2000-04-30T22:00:00.000Z", 
     "length": 155, 
     "plot": "En el año 180, el Imperio Romano domina todo el mundo conocido. Tras una gran victoria sobre los bárbaros del norte, el anciano emperador Marco Aurelio (Richard Harris) decide transferir el poder a Máximo (Russell Crowe), bravo general de sus ejércitos y hombre de inquebrantable lealtad al imperio. Pero su hijo Cómodo (Joaquin Phoenix), que aspiraba al trono, no lo acepta y trata de asesinar a Máximo.", 
     "cover": "img/film_covers/gladiator.jpg", 
     "cast": "Russell Crowe, Joaquin Phoenix, Connie Nielsen, Oliver Reed, Richard Harris, Ralf Moeller, Derek Jacobi, Djimon Hounsou, David Schofield, John Shrapnel, Spencer Treat Clark, Tomas Arana, David Hemmings, Tommy Flanagan, Sven-Ole Thorsen, Tony Curran, Giorgio Cantarini, Omid Djalili, Giannina Facio, Michael Sheen", 
     "downloaddate": null, 
     "alt": "Gladiator", 
     "genre": [ 
     "Action", 
     "Adventure", 
     "Drama", 
     "Historical" 
     ], 
     "id": 3 
    } 
    ], 
    "series": [] 
} 
+0

Все, что angular.forEach собирается сделать это перебирать все объекты и отображения жанра. Любопытно, что вы a) используя angular.foreach вместо Array.forEach и b) почему вы не используете Array.filter, а не просто итерации? –

+0

Этот угловой.forEach предназначен только для целей отладки. Он ничего не делает, кроме отображения в консоли жанров каждого фильма. – joudaon

+0

Правильно, но с вашего вопроса вы пытаетесь отфильтровать? Раньше, у меня не было всего моего кофе, но я не вижу никакой логики фильтрации. –

ответ

0

Это сделает.

let target_genre = 'Adventure'; // what your user selected 
let movies = obj.movies; // your movies array from your JSON 

// Find out if a movie's genres contains the target genre 
// If so, return it to the new array. 
let movies_filtered = movies.filter (x => { 
    return x.genre.indexOf (target_genre) >= 0 }); 

console.log (movies_filtered); // two movies 

Edit: Так как фактическое использование было множество жанров, здесь вы можете проверить «какие-либо жанровые матчи», или «все жанры совпадают». Обратите внимание: теперь это предположение состоит в том, что если он может быть массивом жанров, он всегда должен быть массивом жанров, даже если он длинный, иначе вам придется писать «если это массив, сделайте это так, если не сделайте это так, "код. Если это всегда массив, даже один длинный, вы просто всегда делаете это «это массив».

let target_genres = [ 'Adventure', 'Drama', 'Historical' ]; 
let movies = obj.movies; // your movies array 

// Returns if any genre matches 
let movies_filtered = movies.filter (x => { 
    return target_genres.filter (y => { 
    return x.genre.indexOf (y) >= 0; 
    }).length; // if length is 0, that's "false", anything else is "true". 
}); 

// Returns if all genres match 
let movies_filtered = movies.filter (x => { 
    let originalLength = target_genres.length; 
    return target_genres.filter (y => { 
    return x.genre.indexOf (y) >= 0; 
    }).length === originalLength; // filtered array length must match original length 
}); 
+0

Это сработало! Он возвращает, как вы сказали, массив с 2 фильмами! Теперь я должен приспособить его к моим потребностям! Большое спасибо. – joudaon

+0

Да, это не раздражает, как выглядят простые эти виды алги, когда вы видите ответ. Единственное, что я узнал о algs, - если вам нужно больше нескольких строк кода для проверки базового футляра, вы, вероятно, движетесь в неправильном направлении. Однако map/filter/reduce (fold), а теперь с Sets, union/diff/intersection, являются довольно простыми и наиболее определенно необходимыми для чтения для любого JS-dev. –

+0

Один маленький вопрос, если я хочу передать 2 параметра в жанре? Кто это будет работать? Я попытался: target_genre = ['Приключение', 'Исторический]; Но он возвращает пустой массив – joudaon

0

Вы можете использовать это решение с ES6 :)

const filteredMoviesByGenreType = (data, genreType) => { 
    // access to object with key "movies" in data via spread operator and dot notation and filtering by genreType 
    return [...data.movies] 
    .filter(movie => movie["genre"] 
    .includes(genreType)); 
} 

где данные целые данные JSON от сервера.

например выход для жанров только драмы:

filteredMoviesByGenreType(data, "Drama"); 

[[object Object] { 
    alt: "Los juegos del hambre", 
    cast: "Jennifer Lawrence, Josh Hutcherson, Elizabeth Banks, Woody Harrelson, Donald Sutherland, Stanley Tucci, Liam Hemsworth, Toby Jones, Lenny Kravitz, Wes Bentley, Paula Malcomson, Isabelle Fuhrman, Sandra Ellis Lafferty, Paula Malcomson, Kimiko Gelman, Nelson Ascencio, Brooke Bundy, Amandla Stenberg, Dayo Okeniyi, Leven Rambin, Jack Quaid, Latarsha Rose, Alexander Ludwig, Jacqueline Emerson", 
    cover: "img/film_covers/losjuegosdelhambre.jpg", 
    downloaddate: null, 
    genre: ["Action", "Drama", "Science Fiction"], 
    id: 2, 
    length: 143, 
    plot: "Lo que en el pasado fueron los Estados Unidos, ahora es una nación llamada Panem; un imponente Capitolio ejerce un control riguroso sobre los 12 distritos que lo rodean y que están aislados entre sí. Cada distrito se ve obligado a enviar anualmente un chico y una chica entre los doce y los dieciocho años para que participen en los Hunger Games, unos juegos que son transmitidos en directo por la televisión. Se trata de una lucha a muerte, en la que sólo puede haber un superviviente. Katniss Everdeen, una joven de dieciséis años, decide sustituir a su hermana en los juegos; pero para ella, que ya ha visto la muerte de cerca, la lucha por la supervivencia es su segunda naturaleza.", 
    releasedate: "2011-12-31T23:00:00.000Z", 
    title: "Los juegos del hambre" 
}, [object Object] { 
    alt: "Gladiator", 
    cast: "Russell Crowe, Joaquin Phoenix, Connie Nielsen, Oliver Reed, Richard Harris, Ralf Moeller, Derek Jacobi, Djimon Hounsou, David Schofield, John Shrapnel, Spencer Treat Clark, Tomas Arana, David Hemmings, Tommy Flanagan, Sven-Ole Thorsen, Tony Curran, Giorgio Cantarini, Omid Djalili, Giannina Facio, Michael Sheen", 
    cover: "img/film_covers/gladiator.jpg", 
    downloaddate: null, 
    genre: ["Action", "Adventure", "Drama", "Historical"], 
    id: 3, 
    length: 155, 
    plot: "En el año 180, el Imperio Romano domina todo el mundo conocido. Tras una gran victoria sobre los bárbaros del norte, el anciano emperador Marco Aurelio (Richard Harris) decide transferir el poder a Máximo (Russell Crowe), bravo general de sus ejércitos y hombre de inquebrantable lealtad al imperio. Pero su hijo Cómodo (Joaquin Phoenix), que aspiraba al trono, no lo acepta y trata de asesinar a Máximo.", 
    releasedate: "2000-04-30T22:00:00.000Z", 
    title: "Gladiator" 
}]