I've been going through the RxJS tutorials http://reactivex.io/learnrx/. Almost all of the exercises involve moving from a hierarchical structure to a flat structure so I thought I'd try to do the opposite.
I want to convert from a flat array to a tree structure based on a property of each array item, using the same functional constructs from the tutorial.
I.e. Go from this:
var videos = [
{
"id": 70111470,
"title": "Die Hard",
"category": "Action"
},
{
"id": 654356453,
"title": "Bad Boys",
"category": "Action"
},
{
"id": 65432445,
"title": "Anchorman",
"category": "Comedy"
},
{
"id": 675465,
"title": "Everest",
"category": "New Release"
}
];
To this (based on each video's category):
result === [
{
"category": "Action",
"videos": [
{
"id": 70111470,
"title": "Die Hard"
},
{
"id": 654356453,
"title": "Bad Boys"
}
]
},
{
"category": "Comedy",
"videos": [
{
"id": 65432445,
"title": "Anchorman"
}
]
},
{
"category": "New Release",
"videos": [
{
"id": 675465,
"title": "Everest"
}
]
}
];
I've come up with the following code that works, but I feel like I'm missing an easier way (perhaps solving in a single reduce) which would in turn be more performant (rather than filtering videos many times):
var result =
videos.reduce(function(catArray, video) {
var catName = video.category;
if (catArray.indexOf(catName) === -1) {
catArray.push(catName);
}
return catArray;
}, [])
.map(function(categoryName) {
return {
category: categoryName,
videos: videos.filter(function(video) {
return video.category === categoryName;
}).map(function(video) {
return {
id: video.id,
title: video.title
};
})
};
});
Is there a better way using functional methods?