[ { '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)
Advertisement
Answer
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 )