Reputation: 9790
I have an array of objects, where I want to combine if they have the same name, and add their feederTeams into an array.
The array looks like this:
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'
}]
and I want to transform it into this using Ramda:
[{
name: 'Liverpool',
feederTeam: ['Tranmere', 'Stockport', 'Oldham']
}, {
name: 'Man Utd',
feederTeam: ['Bla'],
}]
I have tried many approaches with no luck. Here is my latest attempt.
R.forEach((team => R.filter(R.propEq('name', team.name), TEAMS)), TEAMS);
Upvotes: 2
Views: 1119
Reputation: 191976
Since you want to group several elements together use R.groupBy. Then get an array from the object of groups with R.values, and map each group to the required form:
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>
A slight variation would be to map the object of groups with R.mapObjIndexed. In this case the name
the key (is the 2nd param supplied to R.applySpec). After mapping the groups to objects, convert the result to an array with R.values:
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>
Upvotes: 3