简体   繁体   中英

Nested complex json data access

 const users = [ { userId: 15291, email: "Constantin_Kuhlman15@yahoo.com", friends: [7001, 51417, 62289] }, { userId: 7001, email: "Keven6@gmail.com", friends: [15291, 51417, 62289, 66380] }, { userId: 51417, email: "Margaretta82@gmail.com", friends: [15291, 7001, 9250] }, { userId: 62289, email: "Marquise.Borer@hotmail.com", friends: [15291, 7001] } ]; const movies = [ { "title": "The Shawshank Redemption", "duration": "PT142M", "actors": [ "Tim Robbins", "Morgan Freeman", "Bob Gunton" ], "ratings": [ { "userId": 7001, "rating": 8 }, { "userId": 9250, "rating": 9 }, { "userId": 34139, "rating": 8 } ], "favorites": [ 66380, 7001, 9250, 34139 ], "watchlist": [ 15291, 51417, 62289, 6146, 71389, 93707 ] }, { "title": "The Godfather", "duration": "PT175M", "actors": [ "Marlon Brando", "Al Pacino", "James Caan" ], "ratings": [ { "userId": 15291, "rating": 9 }, { "userId": 51417, "rating": 9 }, { "userId": 7001, "rating": 9 }, { "userId": 9250, "rating": 7 }, { "userId": 71389, "rating": 9 } ], "favorites": [ 15291, 51417, 7001, 9250, 71389, 93707 ], "watchlist": [ 62289, 66380, 34139, 6146 ] }, { "title": "The Dark Knight", "duration": "PT152M", "actors": [ "Christian Bale", "Heath Ledger", "Aaron Eckhart" ], "ratings": [ { "userId": 15291, "rating": 8 }, { "userId": 7001, "rating": 9 }, { "userId": 9250, "rating": 6 }, { "userId": 34139, "rating": 7 }, { "userId": 93707, "rating": 7 } ], "favorites": [ 15291, 7001, 9250, 34139, 93707 ], "watchlist": [ 51417, 62289, 6146, 71389 ] }, { "title": "Pulp Fiction", "duration": "PT154M", "actors": [ "John Travolta", "Uma Thurman", "Samuel L. Jackson" ], "ratings": [ { "userId": 62289, "rating": 8 }, { "userId": 66380, "rating": 5 }, { "userId": 6146, "rating": 6 }, { "userId": 71389, "rating": 7 } ], "favorites": [ 15291, 51417, 62289, 66380, 71389, 93707 ], "watchlist": [ 7001, 9250, 34139, 6146 ] } ]; // solution class MoviesAnalyzer { constructor(movies, users) { this.movies = movies; this.users = users; } // -- my code topRatedMoviesByFriends(userId) { const user = this.users.filter( user => user.userId === userId )[0]; if (user === undefined) throw 'no such user'; let moviesFriends = {}; for (const movie of this.movies) { let friendsCount = 0; for (const friend of user.friends) { console.log("friend",friend); for (const userId of movie.ratings) { // console.log("userId",userId); if (movie.ratings.includes(userId)) { friendsCount++; } } } if (moviesFriends[friendsCount]) { moviesFriends[friendsCount].push(movie.title); } else if (friendsCount > 0) { moviesFriends[friendsCount] = [movie.title]; } } return moviesFriends; } topRatedMoviesAmongFriends(userId){ const friendsTopRatedlist = this.topRatedMoviesByFriends(userId); let topMovies = []; const sortedKeys = Object.keys(friendsTopRatedlist).sort((a, b) => parseInt(a) < parseInt(b)); for (const key of sortedKeys) { let sortedTitles = friendsTopRatedlist[key].sort(); while (sortedTitles.length > 0 && topMovies.length < 4) { topMovies.push(sortedTitles.shift()); } } return topMovies; } } // test const analyzer = new MoviesAnalyzer(movies, users); console.log(analyzer.topRatedMoviesAmongFriends(62289)); 

  1. topRatedMoviesAmongFriends method that will return an array of top three movie titles, that have the highest average rating among friends of a given user.
  2. When looking for top rated movies, only ratings given by friends of a given user should be considered.
  3. If there are no such movies, then an empty list should be returned.
  4. Movies that have equal rating, should be ordered alphabetically.

for userID 62289, output should be ["pulp fiction", "The Godfather", "The Dark Knight"] I think it's a complex nested loops, And I am not getting the actual expected result and I think iteration is also somewhere wrongs, can someone please correct me that where I am doing wrong?

I think that the output of 62289 is ["The Godfather", "The Dark Knight", "The Shawshank Redemption"] based on the order of average rating of only friends [9, 8.5, 8].

Below is my code.

const users = [
  {
    userId: 15291,
    email: "Constantin_Kuhlman15@yahoo.com",
    friends: [7001, 51417, 62289]
    },
  {
    userId: 7001,
    email: "Keven6@gmail.com",
    friends: [15291, 51417, 62289, 66380]
    },
  {
    userId: 51417,
    email: "Margaretta82@gmail.com",
    friends: [15291, 7001, 9250]
    },
  {
    userId: 62289,
    email: "Marquise.Borer@hotmail.com",
    friends: [15291, 7001]
    }
];

const movies = [
  {
    "title": "The Shawshank Redemption",
    "duration": "PT142M",
    "actors": [
            "Tim Robbins",
            "Morgan Freeman",
            "Bob Gunton"
        ],
    "ratings": [
      {
        "userId": 7001,
        "rating": 8
            },
      {
        "userId": 9250,
        "rating": 9
            },
      {
        "userId": 34139,
        "rating": 8
            }
        ],
    "favorites": [
            66380,
            7001,
            9250,
            34139
        ],
    "watchlist": [
            15291,
            51417,
            62289,
            6146,
            71389,
            93707
        ]
    },
  {
    "title": "The Godfather",
    "duration": "PT175M",
    "actors": [
            "Marlon Brando",
            "Al Pacino",
            "James Caan"
        ],
    "ratings": [
      {
        "userId": 15291,
        "rating": 9
            },
      {
        "userId": 51417,
        "rating": 9
            },
      {
        "userId": 7001,
        "rating": 9
            },
      {
        "userId": 9250,
        "rating": 7
            },
      {
        "userId": 71389,
        "rating": 9
            }
        ],
    "favorites": [
            15291,
            51417,
            7001,
            9250,
            71389,
            93707
        ],
    "watchlist": [
            62289,
            66380,
            34139,
            6146
        ]
    },
  {
    "title": "The Dark Knight",
    "duration": "PT152M",
    "actors": [
            "Christian Bale",
            "Heath Ledger",
            "Aaron Eckhart"
        ],
    "ratings": [
      {
        "userId": 15291,
        "rating": 8
            },
      {
        "userId": 7001,
        "rating": 9
            },
      {
        "userId": 9250,
        "rating": 6
            },
      {
        "userId": 34139,
        "rating": 7
            },
      {
        "userId": 93707,
        "rating": 7
            }
        ],
    "favorites": [
            15291,
            7001,
            9250,
            34139,
            93707
        ],
    "watchlist": [
            51417,
            62289,
            6146,
            71389
        ]
    },
  {
    "title": "Pulp Fiction",
    "duration": "PT154M",
    "actors": [
            "John Travolta",
            "Uma Thurman",
            "Samuel L. Jackson"
        ],
    "ratings": [
      {
        "userId": 62289,
        "rating": 8
            },
      {
        "userId": 66380,
        "rating": 5
            },
      {
        "userId": 6146,
        "rating": 6
            },
      {
        "userId": 71389,
        "rating": 7
            }
        ],
    "favorites": [
            15291,
            51417,
            62289,
            66380,
            71389,
            93707
        ],
    "watchlist": [
            7001,
            9250,
            34139,
            6146
        ]
    }
];

// solution
class MoviesAnalyzer {
  constructor(movies, users) {
    this.movies = movies;
    this.users = users;
  }
  // -- my code
  topRatedMoviesByFriends(userId) {

    const user = this.users.filter(
      user => user.userId === userId
    )[0];
    if (user === undefined) throw 'no such user';

    let moviesFriends = {};
    for (const movie of this.movies) {
      let totalRating = 0;
      let friendsCount = 0;
      for (const friend of user.friends) {
        console.log("friend", friend);
        for (const rating of movie.ratings) {
          //  console.log("userId",userId);
          if (rating.userId == friend) {
            totalRating += rating.rating
            friendsCount++;
          }
        }
      }

      console.log(totalRating)
      const averageRating = totalRating / friendsCount
      if (moviesFriends[averageRating]) {
        moviesFriends[averageRating].push(movie.title);
      } else if (averageRating > 0) {
        moviesFriends[averageRating] = [movie.title];
      }
    }
    console.log(moviesFriends)
    return moviesFriends;
  }

  topRatedMoviesAmongFriends(userId) {

    const friendsTopRatedlist = this.topRatedMoviesByFriends(userId);
    let topMovies = [];
    const sortedKeys = Object.keys(friendsTopRatedlist).sort(this.compareRating);
    console.log(sortedKeys)
    for (const key of sortedKeys) {
      let sortedTitles = friendsTopRatedlist[key].sort();
      while (sortedTitles.length > 0 && topMovies.length < 3) {
        topMovies.push(sortedTitles.shift());
      }
    }
    return topMovies;
  }

  compareRating(a, b) {
    const fa = parseFloat(a)
    const fb = parseFloat(b)

    if (fa < fb) return 1
    else if (fa > fb) return -1
    else return 0
  }


}

// test
const analyzer = new MoviesAnalyzer(movies, users);
console.log(analyzer.topRatedMoviesAmongFriends(62289));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM