помощь в рефакторинге с уменьшением некоторых объектов данных массива в JavaScript - PullRequest
0 голосов
/ 28 мая 2020

Мне нужно сократить данные в массиве профилей таким образом, чтобы конечный объект группировал данные в профиле obj на основе избранного mov ie и пользователей, которым понравился / понравился mov ie. Мне нужно что-то вроде:

{
 'Forrest Gump': ["Nicholas Lain"],
 'Planet Earth 1': ["Jane Jones", "Matthew Johnson"]
}

из следующих объектов данных:

const profiles = [
      {
        id: 1,
        userID: '1',
        favoriteMovieID: '1',
      },
      {
        id: 2,
        userID: '2',
        favoriteMovieID: '1',
      },
      {
        id: 3,
        userID: '4',
        favoriteMovieID: '5',
      }
    ];

    const users = {
      1: {
        id: 1,
        name: 'Jane Cruz',
        userName: 'coder',
      },
      2: {
        id: 2,
        name: 'Matthew Johnson',
        userName: 'mpage',
      }
    };

    const movies = {
      1: {
        id: 1,
        name: 'Planet Earth 1',
      },
      2: {
        id: 2,
        name: 'Selma',
      }
    };

Мне нужны идеи по рефакторингу следующего кода, чтобы он go вернулся к пользователям и фильмам объект, чтобы получить их имена из идентификаторов, которые я записал ниже. Вместо идентификаторов мне нужно записывать имена.

profiles.reduce(function (acc, obj) {
    let key = obj['favoriteMovieID']
    if (!acc[key]) {
      acc[key] = []
    }
    acc[key].push(obj.userID)
    return acc
  }, {})

1 Ответ

1 голос
/ 28 мая 2020

Вот одна из техник: сворачивание профилей, захват mov ie и имен людей внутри параметров, а затем просто запись нового аккумулятора с этими данными. Обратите внимание, что при этом возникает потенциальная проблема с производительностью, как описано в отличной статье Rich Snapp . Если это вызывает у вас реальную проблему, достаточно легко изменить это, чтобы изменить аккумулятор.

Я добавил некоторые дополнительные данные, чтобы показать, что происходит, когда пользователь или mov ie отсутствуют в соответствующих списках . Если этого никогда не произойдет, вы можете немного упростить объявления name и person. Но я бы не рекомендовал это, поскольку вещи, которые "никогда не могут случиться", на самом деле происходят регулярно.

const groupNamesByMovie = (profiles, users, movies) => 
  profiles .reduce ((
    a, {userID, favoriteMovieID}, _, __, 
    {name} = movies [favoriteMovieID] || {name: 'Unknown Movie'},
    {name: person} = users [userID] || {name: 'Unknown Person'}
  ) => ({
    ...a,
    [name]: [... (a [name] || []), person]
  }), {})

const profiles = [{id: 1, userID: "1", favoriteMovieID: "1"}, {id: 2, userID: "2", favoriteMovieID: "1"}, {id: 3, userID: "4", favoriteMovieID: "5"}, {id: 4, userID: "6", favoriteMovieID: "5"}, {id: 5, userID: "5", favoriteMovieID: "7"}]
const users = {1: {id: 1, name: "Jane Cruz", userName: "coder"}, 2: {id: 2, name: "Matthew Johnson", userName: "mpage"}, 4: {id: 4, name: "Nicholas Lain", userName: "nlain"}, 5: {id: 5, name: "Fred Flintstone", userName: "bedrock1"}}
const movies = {1: {id: 1, name: 'Planet Earth 1'}, 2: {id: 2, name: 'Selma'}, 5: {id: 5, name: 'Forrest Gump'}}

console .log (
  groupNamesByMovie (profiles, users, movies)
)

Обратите внимание, что аргументы _ и __ предназначены только для использования в качестве заполнителей, поскольку нас не волнуют reduce index и array параметры.

Обновление

Поступил запрос на уточнение. Для сравнения, вот более императивная версия той же идеи:

const getNamesByMovie = (profiles, users, movies) =>
  profiles .reduce ((acc, {userID, favoriteMovieID}) => {
    const movie = movies [favoriteMovieID]
    const name = movie ? movie.name : 'Unknown Movie'
    const user = users [userID]
    const person = user ? user.name : 'Unknown Person'
    const fans = acc [name] || []
    return {
      ... acc,
      [name]: [... fans, person]
    }

  }, {})

И если вы хотите избежать этой потенциальной проблемы с производительностью, вы можете заменить оператор return чем-то вроде этого:

    acc [name] = fans
    fans .push (person)
    return acc

Любой из них делает то же самое, что и оригинал выше. Я выбираю этот начальный стиль, потому что мне не нравится изменять объект-аккумулятор, я предпочитаю всегда создавать новую версию ... и потому что я предпочитаю работать с выражениями, а не с операторами. Но к этому стилю нужно привыкнуть.

Вы также спросили, как мы передали дополнительные параметры в обратный вызов reduce. Мы этого не делаем. Вместо этого мы определяем некоторые дополнительные параметры и инициализируем их на основе более ранних параметров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...