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
}
}, {})
const registeredUsers = Object.values(usersById).filter(user => user.registered);
Сравните результаты:
{
"5": {
"id": "5",
"name": "Adam",
"registered": true
},
"27": {
"id": "27",
"name": "Bobby",
"registered": true
},
"39": {
"id": "39",
"name": "Danielle",
"registered": true
}
}
[
{
"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()
вы правы, так проще.
del
Функциональщина это, конечно, круто, но почему бы просто не использовать 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 и мне важно понять как делать правильно.
For-of не работает на объектах. Придётся итератор писать, оно вам надо? :)
For-in тут самое место. Ну, для особо осторожных, можно добавить
if (usersById.hasOwnProperty('prop')) {… }
Но, честно говоря, я не могу быстро представить как надо извратиться, что-бы в подобном случае «получить пользователей с идентификаторами toString».
- Поставь setTimeout(() => {}, 0) должно помочь! Если не поможет, то поменяй 0 на 100;
- Если падает "...expression has changed after it was checked...", то советуют в случайных местах повтыкать cdr;
- Если не понимают как работает DI, То советуют ВСЁ вытащить в рут-модуль, либо наоборот продублировать во всех чалдовых.
Список можно продолжать очень долго, первое что мгновенно всплыло. А уж какие советы дают «по борьбе с rxjs» совсем песня… количество семафоров, флажков и прочих подпорок поражает воображение.
Object.values(usersById).filter(user => user.registered)
Теория вместо эвристики: становимся лучше как frontend-разработчики