[
{
'members': {
'infants': [{ 'name': 'A' }],
'adults': [{ 'name': 'B' }, { 'name': 'C' }],
'children': [{ 'name': 'D' }],
},
},
{
'members': {
'infants': [],
'adults': [{ 'name': 'F' }, { 'name': 'G' }, { 'name': 'H' }],
'children': [],
},
},
]
Here is how my data object looks like
and I tried to implement it like
const travelerCounter = compose(
length,
unnest,
unnest,
map(values),
unnest,
pluck('members')
)
I am not sure if it is a good solution or we can write it in compact way. It also shows the correct number but if I try to use it in TypeScript I am a TS error ts(2769)
CodePudding user response:
You can use R.chain
with R.values
and then flatten to a single array:
const { compose, length, flatten, chain, values, pluck } = R
const fn = compose(
length, // get the length
flatten, // flatten to a single array
chain(values), // combine the values of all member objects
pluck('members') // get members objects
)
const data = [{"members":{"infants":[{"name":"A"}],"adults":[{"name":"B"},{"name":"C"}],"children":[{"name":"D"}]}},{"members":{"infants":[],"adults":[{"name":"F"},{"name":"G"},{"name":"H"}],"children":[]}}]
const result = fn(data)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js" integrity="sha512-t0vPcE8ynwIFovsylwUuLPIbdhDj6fav2prN9fEu/VYBupsmrmk9x43Hvnt Mgn2h5YPSJOk7PMo9zIeGedD1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
TS types:
type Members = { members: Record<string, { name: string }[]> };
const fn: (v: Members[]) => number = compose(
length, // get the length
flatten, // flatten to a single array
chain(values), // combine the values of all member objects
pluck("members") // get members objects
);
Instead of flattening, you can also pluck the lengths, and then sum them:
const { compose, sum, pluck, length, chain, values } = R
const fn = compose(
sum, // sum the lengths
pluck('length'), // get the length of each members array
chain(values), // combine values of all members objects
pluck('members') // get members objects
)
const data = [{"members":{"infants":[{"name":"A"}],"adults":[{"name":"B"},{"name":"C"}],"children":[{"name":"D"}]}},{"members":{"infants":[],"adults":[{"name":"F"},{"name":"G"},{"name":"H"}],"children":[]}}]
const result = fn(data)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js" integrity="sha512-t0vPcE8ynwIFovsylwUuLPIbdhDj6fav2prN9fEu/VYBupsmrmk9x43Hvnt Mgn2h5YPSJOk7PMo9zIeGedD1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
TS types - in this case TS can't infer the types inside R.compose, so we'll need to provide a more verbose signature:
type Member = { name: string };
type MembersRecords = Record<string, Member[]>;
type Members = { members: MembersRecords };
const fn = compose<[Members[]], MembersRecords[], Member[][], number[], number>(
sum, // sum the lengths
pluck('length'), // get the length of each members array
chain(values), // combine values of all members objects
pluck('members') // get members objects
)