With Javascript, I want to split an array and group by an attribute
input:
[
{
"type": "typeA",
"label": "labelA",
"placeholders": [
"b",
"a",
"r"
]
},{
"type": "typeB",
"label": "labelB",
"placeholders": [
"x",
"y",
"z"
]
},{
"type": "typeA",
"label": "labelAAA",
"placeholders": [
"a",
"b",
"c"
]
}
]
I want output:
[
{
"type": "typeA",
"items": [
{
"label": "labelA",
"placeholders": [
"b",
"a",
"r"
]
},
{
"label": "labelAAA",
"placeholders": [
"a",
"b",
"c"
]
}
]
},
{
"type": "typeB",
"items": [
{
"label": "labelB",
"placeholders": [
"b",
"a",
"r"
]
}
]
}
]
I think javascript use .reduce
, .concat
, .map
, …
I’d like to do this without additional libraries (e.g., lodash).
4
Answers
Here is an example I created in JSFiddle that should get you the result you’re looking for.
https://jsfiddle.net/9kman64x/
It uses the reduce method on the array and either adds it to a known group or makes a new one.
As I said in comments, since you’re grouping by
type
– making it basically unique per se, you would be better going for an Object as response (instead of array). It’s easier to do so, and easier to retrieve data from:then, to get the length of your groups use:
or to get an Array (as requested, but which I think is not necessary), use:
One of the best ways to approach this is to reduce the array into a
Map
and group bytype
.Calling
Map.prototype.values()
returns an iterator, so you will need to convert to an array via:Array.from(iterator)
or[...iterator]
(spread oprator)You could do something like this:
The idea is to incrementally build the new array, checking if we have already seen a certain type. If we have, add it to the list of items; otherwise, create a new entry.
It’s not the most optimal solution because we have to loop through every type to see if we have a match on each iteration.