Pull to refresh

Comments 21

Object.keys(usersById).map(id => usersById[id]).filter(user => user.registered)

Вообще-то, довольно странный путь.
Во-первых, в функцию map попадает что-то из внешней области видимости, (что впоследствии может привести к излишнему каррированию).
А во-вторых, почему бы не сэкономить лишний пробег, воспользовавшись Object.values или же Object.entries?
А в-третьих, функция, принимающая на входе объект-коллекцию, почему-то выдает массив, не то, что будет ожидать следующий разработчик.


Object.fromEntries(Object.entries(usersById).filter(([id, user]) => user.registered))
// Object.fromEntries можно заменить на функцию-помощник, написанную через reduce

Методы fromEntries и entries ещё не вошли в стандарт. Через reduce надёжней:


 const registredUsersById = Object.values(usersById).reduce((result, user) => {
        if(!user.registered) return result
        return {
            ...result,
            [user.id]: user
        }
    }, {})
`Object.entries` уже в стандарте ES2017,
Зачем столько кода? Вот же самый короткий и рабочий путь.
const registeredUsers = Object.values(usersById).filter(user => user.registered);

Сравните результаты:


.reduce()
{
  "5": {
    "id": "5",
    "name": "Adam",
    "registered": true
  },
  "27": {
    "id": "27",
    "name": "Bobby",
    "registered": true
  },
  "39": {
    "id": "39",
    "name": "Danielle",
    "registered": true
  }
}

.filter()
[
  {
    "id": "5",
    "name": "Adam",
    "registered": true
  },
  {
    "id": "27",
    "name": "Bobby",
    "registered": true
  },
  {
    "id": "39",
    "name": "Danielle",
    "registered": true
  }
]

reduce — возвращает объект, а filterмассив

Разработчик должен не только понимать технические особенности реализации, но и быть внимательным к условиям поставленной задачи, а именно:

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

Увидеть, что теперь у вас есть массив пользовательских объектов, который можно фильтровать и который содержит действительные значения, которые вы хотите отфильтровать:

Object.keys(usersById).map(id => usersById[id]).filter(user => user.registered)

Пойди Билл этим путем, он мог бы работать у нас.

Постановка задачи не включала информацию о формате выходных данных

Ну как же нет? В переводе рассматривается абстрактный пример на собеседовании некоего Билла. Ниже цитата из перевода, от этого условия скачет дальнейший код, в этом условии просят извлечь список. Более того, результат в виде массива логичен и может быть обоснован дальнейшим использованием, то есть если мы получим отфильтрованный объект, то для отрисовки данных нам снова придется приводить его к массиву.
Допустим, Биллу нужно извлечь список зарегистрированных пользователей.
Если бы

Размышления о том, что на выходе он мог бы получить массив, находятся в секции после постановки задачи.


Вся задача укладывается в одно предложение:


Биллу нужно извлечь список зарегистрированных пользователей.

Но про Object.values() вы правы, так проще.

Тут да, спорить не буду, хотя в каком-то смысле это можно отнести к придиркам. Но оставим это на совести автора.
Размышления о том, что на выходе он мог бы получить массив, находятся в секции после постановки задачи.

Функциональщина это, конечно, круто, но почему бы просто не использовать for in?
Минус два прохода по всем элементам массива


const usersById = {
    "5": { "id": "5", "name": "Adam", "registered": true },
    "27": { "id": "27", "name": "Bobby", "registered": true },
    "32": { "id": "32", "name": "Clarence", "registered": false },
    "39": { "id": "39", "name": "Danielle", "registered": true },
    "42": { "id": "42", "name": "Ekaterina", "registered": false }
}
const result = [];
for(let key in usersById) {
    if(usersById[key].registered) {
      result.push(usersById[key]);
    }
}

И однажды случайно получить "пользователей" с идентификаторами toString и пр.?


Тогда уж надо цикл for-of использовать...

А можно узнать про это поподробнее? Или где можно почитать про это?
Просто сама только начала учить JavaScript и мне важно понять как делать правильно.
Спасибо, обязательно прочитаю.

Можно поглядеть На MDN.


Суть в том, чтобы отфильтровать "чужие" свойства из prototype chain.

Не слушайте. :)
For-of не работает на объектах. Придётся итератор писать, оно вам надо? :)
For-in тут самое место. Ну, для особо осторожных, можно добавить
if (usersById.hasOwnProperty('prop')) {… }
Но, честно говоря, я не могу быстро представить как надо извратиться, что-бы в подобном случае «получить пользователей с идентификаторами toString».
Особенно плакать хочется, когда на все проблемы в ангуляре, люди закидывают в ответы вредные советы вида:
  1. Поставь setTimeout(() => {}, 0) должно помочь! Если не поможет, то поменяй 0 на 100;
  2. Если падает "...expression has changed after it was checked...", то советуют в случайных местах повтыкать cdr;
  3. Если не понимают как работает DI, То советуют ВСЁ вытащить в рут-модуль, либо наоборот продублировать во всех чалдовых.

Список можно продолжать очень долго, первое что мгновенно всплыло. А уж какие советы дают «по борьбе с rxjs» совсем песня… количество семафоров, флажков и прочих подпорок поражает воображение.
Вы сравниваете не эвристику с теорией, а неопытного разработчика с опытным.
Почему не использовать метод values?
Object.values(usersById).filter(user => user.registered)
Sign up to leave a comment.