Lodash _.map для получения свойств массива объектов - PullRequest
1 голос
/ 17 мая 2019

У меня есть массив объектов, таких как:

    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',['missing!'] должно быть возвращено.

То, что я пробовал и не работало:

getUserNamesById(id: string) string[] {
   return _.map(this.users, user => {
         return _.find(user.ids,{id});
});}

Это не работает, а также не относится к случаю, когдавы не находите Id, и он возвращает ['missing'] (а также не возвращает свойство name).

Я новичок в _.lodash и хочу его изучить, но я исследовал почти 2 часа и ничего не получил.

Как мне достичь результата?

Ответы [ 2 ]

1 голос
/ 17 мая 2019

Вы можете использовать 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.log(filterById('C.001.001', users));
console.log(filterById('132133333', users));

И та же идея с lodash / 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.log(filterById('C.001.001')(users));
console.log(filterById('132133333')(users));
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
1 голос
/ 17 мая 2019

Вам нужно разобраться с «отсутствующим» делом отдельно.

Вам нужно отфильтровать список, чтобы получить то, что соответствует
если есть совпадения, карту, чтобы получить имя
иначе получите «недостающую» запись

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.log(find(users, 'C.001.001'));
console.log(find(users, 'C.123.456'));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
...