I'm trying to upgrade my javascript to be more functional. I have used function composition and curry successful on less complicated code but i'm now running into a point where i'm not sure on how to approach it.
Given the below relational data structures.
// Contains all node types and its property definitions. Including any additional information like readable descriptions etc..
const nodes = [{
id: '0ec7deff-91af-e911-812a-00155d0a5146',
description: 'Airplanes',
properties: [{
id: '0fc7deff-91af-e911-812a-00155d0a5146',
description: 'Weight'
}, {
id: '06c7deff-91af-e911-812a-00155d0a5146',
description: 'Color'
}]
}, {
id: '278182d0-4ba2-4813-b74e-277a2296e864',
description: 'Manufacturers',
properties: [{
id: '003e14d7-c11a-41e1-ad08-ab8896a3cb55',
description: 'Boeing'
}]
}]
// Contains only the to be used nodes and there relations(defined through children nodes) in the eventual output. The above definitions can be used to pull in additional data.
const rootNode = {
id: '0ec7deff-91af-e911-812a-00155d0a5146',
properties: [{
id: '0fc7deff-91af-e911-812a-00155d0a5146',
}],
children: [{
id: '278182d0-4ba2-4813-b74e-277a2296e864',
properties: [{
id: '003e14d7-c11a-41e1-ad08-ab8896a3cb55',
}]
}],
}
The rootNode is the starting point. It can contain an infinite amount of children including properties that need to be displayed. Each node needs to be checked for child nodes and be added to the eventual result. For example a linear set to be displayed on the x axis where the properties will be shown on a next row also on the x axis.
[{
id: '0ec7deff-91af-e911-812a-00155d0a5146',
description: 'Airplanes',
properties: [{
id: '0fc7deff-91af-e911-812a-00155d0a5146',
description: 'Weight'
}]
}, {
id: '278182d0-4ba2-4813-b74e-277a2296e864',
description: 'Manufacturers',
properties: [{
id: '003e14d7-c11a-41e1-ad08-ab8896a3cb55',
description: 'Boeing'
}]
}]
The eventual output will be shown in a 2 dimensional grid or table.
Airplanes Manufacturers
Weight Boeing
Or in a more elaborate example if i would provide more data and a larger query.
Airplanes Manufacturers
Weight Color Type Boeing Lockhead
I build a function that works and uses recursion but it just doesn't feel right. I want to pull it apart into smaller units. Note that lodash is used here, hence the shorthands etc.
function initializeNodeMapper(nodes) {
const result = []
return function mapNodes(node) {
const usedPropertyIds = map(node.properties, 'id')
const currentNode = find(nodes, ['id', node.id])
const nodeWithReducedProperties = reduce(currentNode, (acc, value) => ({
...acc,
properties: filter(value, property => indexOf(usedPropertyIds, property.id) !== -1),
}), currentNode)
result.push(nodeWithReducedProperties)
if (node.children && node.children.length > 0) {
forEach(node.children, mapNodes)
}
return result
}
}
const mapData = initializeNodeMapper(nodes)
const mappedData = mapData(initialNode)
Using functional patterns i want to find a more optimal pattern of mapping and testing the code.