#javascript #ecmascript-6 #ramda.js
#javascript #ecmascript-6 #ramda.js
Вопрос:
У меня есть массив объектов, где я хочу объединить, если они имеют одинаковое имя, и добавить их группы фидеров в массив.
Массив выглядит следующим образом:
const TEAMS = [{
name: 'Liverpool',
id: '1',
feederTeam: 'Tranmere'
}, {
name: 'Liverpool',
id: '2',
feederTeam: 'Stockport'
}, {
name: 'Man Utd',
feederTeam: 'Bla',
id: '3',
}, {
name: 'Liverpool',
id: '6',
feederTeam: 'Oldham'
}]
и я хочу преобразовать его в это, используя Ramda:
[{
name: 'Liverpool',
feederTeam: ['Tranmere', 'Stockport', 'Oldham']
}, {
name: 'Man Utd',
feederTeam: ['Bla'],
}]
Я пробовал много подходов, но безуспешно. Вот моя последняя попытка.
R.forEach((team => R.filter(R.propEq('name', team.name), TEAMS)), TEAMS);
Ответ №1:
Поскольку вы хотите сгруппировать несколько элементов вместе, используйте R.groupBy. Затем получить массив из объекта групп со значениями R. и сопоставить каждую группу с требуемой формой:
const { pipe, groupBy, prop, values, map, applySpec, nth } = R
const fn = pipe(
groupBy(prop('name')), // group object by the name property
values, // get an array of groups
map(applySpec({ // map each group to an object
name: pipe(nth(0), prop('name')), // take the name from the 1st object in the group
feederTeam: map(prop('feederTeam')), // collect all feedTeam props to an array
})),
)
const teams = [{"name":"Liverpool","id":"1","feederTeam":"Tranmere"},{"name":"Liverpool","id":"2","feederTeam":"Stockport"},{"name":"Man Utd","feederTeam":"Bla","id":"3"},{"name":"Liverpool","id":"6","feederTeam":"Oldham"}]
const result = fn(teams)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous"></script>
Небольшим изменением было бы сопоставление объекта групп с R.mapObjIndexed. В этом случае name
ключ (это 2-й параметр, предоставленный R.applySpec). После сопоставления групп с объектами преобразуйте результат в массив со значениями R.:
const { pipe, groupBy, prop, values, mapObjIndexed, applySpec, map, nthArg } = R
const fn = pipe(
groupBy(prop('name')), // group object by the name property
mapObjIndexed(applySpec({ // map each group to an object
name: nthArg(1), // take the name from key (2nd arg)
feederTeam: map(prop('feederTeam')), // collect all feedTeam props to an array
})),
values, // convert to an array of objects
)
const teams = [{"name":"Liverpool","id":"1","feederTeam":"Tranmere"},{"name":"Liverpool","id":"2","feederTeam":"Stockport"},{"name":"Man Utd","feederTeam":"Bla","id":"3"},{"name":"Liverpool","id":"6","feederTeam":"Oldham"}]
const result = fn(teams)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous"></script>