I have an array of objects like this:
[
{ name: "Group 1", value: "Foo" },
{ name: "Group 2", value: "Bar" },
{ name: "Group 1", value: "Baz" }
]
I'd like to use Partial Lenses library to transform these groups to keys of an object with corresponding group's items, like this:
{
"Group 1": [
{ name: "Group 1", value: "Foo" },
{ name: "Group 1", value: "Baz" }
],
"Group 2": [
{ name: "Group 2", value: "Bar" }
]
}
My current approach is like this, assuming I have the source data in a variable called data
:
const grouped = L.collect([L.groupBy('name'), L.entries], data)
const setKey = [L.elems, 0]
const getName = [L.elems, 1, 0, 'name']
const correctPairs = L.disperse(setKey, L.collectTotal(getName, grouped), grouped)
L.get(L.inverse(L.keyed), correctPairs)
I don't like that I need to use the grouped
and correctPairs
variables to hold data, as I probably should be able to do the transformation directly in the composition. Could you help me to compose the same functionality in a more meaningful way?
Here's a Partial Lenses Playground with the above code.
You can use Array.reduce
You don't need any library, use a generic function that returns a reducer, that way you can use to group any collection with any key. In the example below I used this to group by name, but also by value.
I assume the goal is to actually create an isomorphism through which one can view such an array as an object of arrays and also perform updates. Like a bidirectional version of e.g. Ramda's
R.groupBy
function.Indeed, one approach would be to just use Ramda's
R.groupBy
to implement a new primitive isomorphism usingL.iso
. Something like this:The conditionals are needed to allow for the possibility that the data is not of the expected type and to map the result to
undefined
in case it isn't.Here is a playground with the above Ramda based
objectBy
implementation.Using only the current version of Partial Lenses, one way to compose a similar
objectBy
combinator would be as follows:Perhaps the interesting part in the above is the middle part that converts an array of arrays into an array of key-array pairs (or the other way around).
L.unzipWith1
checks that all the keys within a group match, and if they don't, that group will be mapped toundefined
and filtered out byL.array
. If desired, it is possible to get stricter behaviour by usingL.arrays
.Here is a playground with the above composed
objectBy
implementation.