現在のプロジェクトでは、次のような形式のデータを返す API を使用しています。
{
groups: [
{
items: [
{
points: [
{ name: "name1", ... },
{ name: "name2", ... },
{ name: "name3", ... },
...
],
...
},
...
]
},
...
],
...
};
上記の形式のオブジェクトと、それぞれを にマッピングするオブジェクトを取り、同じ構造を返しますが、それぞれに対応する を含む純粋な関数を作成したいと思います。mapValues
name
value
point
value
name
たとえば、呼び出すと次のようにmapValues(data, { name1: "value1", name2: "value2", name3: "value3" })
返されます。
{
groups: [
{
items: [
{
points: [
{ name: "name1", value: "value1", ... },
{ name: "name2", value: "value2", ... },
{ name: "name3", value: "value3", ... },
...
],
...
},
...
]
},
...
],
...
};
これが私の最初のパスです:
function mapValues(data, values) {
return _.extend({}, data, {
groups: _.map(ui.groups, (group) => {
return _.extend({}, group, {
items: _.map(group.items, (item) => {
return _.extend({}, item, {
points: _.map(item.points, (point) => {
return _.extend({ value: values[point.name] }, point);
})
});
})
});
})
});
}
これは機能しますが、重複するコードをかなり入れ子にしています。2 回目の試行では、再帰に到達しました。
function mapValues(data, values) {
return (function recursiveMap(object, attributes) {
if (attributes.length === 0) { return _.extend({ value: values[object.name] }, object); }
let key = attributes[0];
return _.extend({}, object, {
[key]: _.map(object[key], child => recursiveMap(child, attributes.slice(1)))
});
})(ui, ["groups", "items", "points"]);
}
これも機能しますが、読みにくく、あまり簡潔ではありません。
Lodash を使用してオブジェクトを再帰的にマップするよりクリーンな方法はありますか? 理想的には、機能的なアプローチを探しています。