У меня есть массив таких объектов:
users: [
{ name: 'missing!', ids: ['Not Specified']},
{ name: 'user1', ids: ['C.001', 'C.002', 'C.001.001']},
{ name: 'user2', ids: ['C.001', 'C.002', 'C.004', 'C.001.001']},
{ name: 'user3', ids: ['C.001', 'C.002', 'C.004', 'C.001.001']},
{ name: 'user4', ids: ['C.001', 'C.002', 'C.004', 'C.001.001']}
]
И чего я хочу добиться, так это получить массив имен пользователей с определенным идентификатором, который был передан.
Например, если я передаю идентификатор: 'C.001.001', должны быть возвращены ['user1','user2','user3','user4'].
Если я передам "C.123214123", должно быть возвращено ["отсутствует!"].
Что я пробовал и не работал:
getUserNamesById(id: string) string[] {
return _.map(this.users, user => {
return _.find(user.ids,{id});
});}
Это не работает, а также не обрабатывает случай, когда вы не можете найти идентификатор, и он возвращает ['отсутствует'] (и также не возвращает свойство имени, если на то пошло).
Я новичок в _.lodash и хочу изучить его, но я исследовал почти 2 часа и ничего не добился.
Как мне добиться результата?
Вам нужно обрабатывать «отсутствующий» случай отдельно.
Вам нужно отфильтровать список, чтобы получить то, что соответствует
если есть совпадения, сопоставьте, чтобы получить имя
иначе получить "отсутствующую" запись
const users = [
{ name: 'missing!', ids: ['Not Specified']},
{ name: 'user1', ids: ['C.001', 'C.002', 'C.001.001']},
{ name: 'user2', ids: ['C.001', 'C.002', 'C.004', 'C.001.001']},
{ name: 'user3', ids: ['C.001', 'C.002', 'C.004', 'C.001.001']},
{ name: 'user4', ids: ['C.001', 'C.002', 'C.004', 'C.001.001']}
];
function find(u, search) {
const found = _.filter(u, (x) => _.some(x.ids, (id) => id === search));
if (_.isEmpty(found)) {
return ['missing!'];
} else {
return _.map(found, (f) => f.name);
}
}
console.info(find(users, 'C.001.001'));
console.info(find(users, 'C.123.456'));
<script src = "https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
Вы можете использовать Array.filtered()
с Array.includes()
(или эквивалентами lodash) для фильтрации массива, а затем Array.map()
для получения списка имен:
const filterById = (id, arr) => {
const filtered = arr.filter(({ ids }) => ids.includes(id))
.map(({ name }) => name);
return filtered.length ? filtered : ['missing'];
}
const users = [{"name":"missing!","ids":["Not Specified"]},{"name":"user1","ids":["C.001","C.002","C.001.001"]},{"name":"user2","ids":["C.001","C.002","C.004","C.001.001"]},{"name":"user3","ids":["C.001","C.002","C.004","C.001.001"]},{"name":"user4","ids":["C.001","C.002","C.004","C.001.001"]}]
console.info(filterById('C.001.001', users));
console.info(filterById('132133333', users));
И та же идея с Лодаш/fp:
const { flow, filter, get, includes, map, cond, isEmpty, constant, stubtrue, identity } = _
const filterById = id => flow(
filter(flow(get('ids'), includes(id))),
cond([
[isEmpty, constant(['missing'])],
[stubtrue, map('name')]
])
)
const users = [{"name":"missing!","ids":["Not Specified"]},{"name":"user1","ids":["C.001","C.002","C.001.001"]},{"name":"user2","ids":["C.001","C.002","C.004","C.001.001"]},{"name":"user3","ids":["C.001","C.002","C.004","C.001.001"]},{"name":"user4","ids":["C.001","C.002","C.004","C.001.001"]}]
console.info(filterById('C.001.001')(users));
console.info(filterById('132133333')(users));
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
Я использовал ответ @crashmstr и объединил его с вашим использованием оператора elvis, поскольку это кажется «более чистым» подходом. большое спасибо :)