I have this array of arrays with objects:
const data = [
[
{
index: 320,
blocks: 2,
value: '31011784785',
participants: 1222,
cost: '1286828506'
},
{
index: 319,
blocks: 0,
value: '111306385',
participants: 18,
cost: '0'
},
{
index: 318,
blocks: 0,
value: '14550473',
participants: 10,
cost: '0'
}
],
[
{
index: 320,
blocks: 1,
value: '7089001673',
participants: 492,
cost: '648196615'
},
{
index: 319,
blocks: 0,
value: '13551137',
participants: 8,
cost: '0'
},
{
index: 318,
blocks: 0,
value: '11499815',
participants: 5,
cost: '0'
}
],
[
{
index: 320,
blocks: 1,
value: '408900161',
participants: 200,
cost: '648196615'
},
{
index: 319,
blocks: 0,
value: '23551231',
participants: 10,
cost: '0'
},
{
index: 318,
blocks: 0,
value: '104324219',
participants: 5,
cost: '0'
}
]
]
I would like to make a single array with objects that will have just the properties index, value, and participants where value and participants will be the sum of the 3 arrays. Eg:
[
{
index: 320,
value: 38509686619,
participants: 1914,
},
{
index: 319,
value: 148408753,
participants: 36,
},
{
...
}
]
I would also like the value field to be a BigInt.
Inspired by this answer I made something that works but it's way too long and cumbersome.
This question is different from Reduce Array of Array of Objects Using Ramda because I need two object property values and I don't know how to do this.
CodePudding user response:
After flattening, the array of arrays, you should map and pick the wanted properties and convert values
to a number, and then group by, and combine each group to a single object.
const { mergeWithKey, pipe, flatten, map, pick, evolve, groupBy, prop, reduce, values } = R
// merge deep and combine properties value
const combine = mergeWithKey((k, l, r) => k === 'value' || k === 'participants' ? l r : r)
const mergeData = pipe(
flatten, // flatten to a single array
map(pipe(
pick(['index', 'value', 'participants']), // pick wanted properties
evolve({ value: Number }) // convert values to a number
)),
groupBy(prop('index')), // group by the name
map(reduce(combine, {})), // combine each group to a single object
values, // convert back to array
)
const data = [[{"index":320,"blocks":2,"value":"31011784785","participants":1222,"cost":"1286828506"},{"index":319,"blocks":0,"value":"111306385","participants":18,"cost":"0"},{"index":318,"blocks":0,"value":"14550473","participants":10,"cost":"0"}],[{"index":320,"blocks":1,"value":"7089001673","participants":492,"cost":"648196615"},{"index":319,"blocks":0,"value":"13551137","participants":8,"cost":"0"},{"index":318,"blocks":0,"value":"11499815","participants":5,"cost":"0"}],[{"index":320,"blocks":1,"value":"408900161","participants":200,"cost":"648196615"},{"index":319,"blocks":0,"value":"23551231","participants":10,"cost":"0"},{"index":318,"blocks":0,"value":"104324219","participants":5,"cost":"0"}]]
const results = mergeData(data)
console.log(results)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
CodePudding user response:
Vanila JS solution:
const data = [[{"index":320,"blocks":2,"value":"31011784785","participants":1222,"cost":"1286828506"},{"index":319,"blocks":0,"value":"111306385","participants":18,"cost":"0"},{"index":318,"blocks":0,"value":"14550473","participants":10,"cost":"0"}],[{"index":320,"blocks":1,"value":"7089001673","participants":492,"cost":"648196615"},{"index":319,"blocks":0,"value":"13551137","participants":8,"cost":"0"},{"index":318,"blocks":0,"value":"11499815","participants":5,"cost":"0"}],[{"index":320,"blocks":1,"value":"408900161","participants":200,"cost":"648196615"},{"index":319,"blocks":0,"value":"23551231","participants":10,"cost":"0"},{"index":318,"blocks":0,"value":"104324219","participants":5,"cost":"0"}]];
const result = Object.values(data.flat()
.reduce((acc, { index, value, participants }) => {
acc[index] ??= { index, value: 0, participants: 0 };
acc[index].value = Number(value);
acc[index].participants = Number(participants);
return acc;
}, {}));
console.log(result);
.as-console-wrapper{min-height: 100%!important; top: 0}