使用 Ramda 镜头更改多个对象
Changing multiple objects using Ramda lens
我目前的数据结构大致如下所示:
var data = { "id": 123,
"modules": [{
"id": 1,
"results": [{
"status": "fail",
"issues": [
{"type": "change", "status": "warn", "data": {}},
{"type": "remove", "status": "warn", "data": {}},
{"type": "change", "status": "warn", "data": {}}
]
}]
},{
"id": 2
"results": [{
"status": "pass",
"issues": [
{"type": "change", "status": "warn", "data": {}},
{"type": "remove", "status": "warn", "data": {}},
{"type": "change", "status": "warn", "data": {}}
]
}]
}]
}
我一直在尝试使用 Ramda 来编写一个组合查询,它可以执行类似的操作,更改特定类型的所有问题的状态。
我一直在尝试按照通过 R.map/R.chain 组合镜头的方式做一些事情,但我似乎无法解决。我正在尝试做这样的事情:
let approvedData = R.compose(
R.set(R.__, 'approve', Data)
R.lensProp('status')
R.map(R.lensIndex),
R.lensProp('issues'),
R.map(R.lensIndex),
R.lensProp('results'),
R.map(R.lensIndex),
R.lensProp('modules')
)(Data)
并让它 return 返回状态已更改的完整数据集。
更新:
我已经想出了一些代码来完成我想做的事情,但我仍在努力将每个步骤变成可以组合的函数:
R.over(R.lensProp('modules'), R.map(
R.over(R.lensProp('results'), R.map(
R.over(R.lensProp('issues'), R.map(
R.set(R.lensProp('status'), 'approve')
))
))
), Data)
看来您可能对数组内值的转换有疑问。
现在,数据为
const data = {
"id": 123,
"modules": [{
"id": 1,
"results": [{
"status": "fail",
"issues": [
{"type": "change", "status": "warn", "data": {}},
{"type": "remove", "status": "warn", "data": {}},
{"type": "change", "status": "warn", "data": {}}
]
}]
},{
"id": 2,
"results": [{
"status": "pass",
"issues": [
{"type": "change", "status": "warn", "data": {}},
{"type": "remove", "status": "warn", "data": {}},
{"type": "change", "status": "warn", "data": {}}
]
}]
}]
};
您要做的是为包含数组的每个键创建透镜。在您的具体情况下,它们是 modules
、results
和 issues
.
最重要的是,您需要一个镜头到您想要修改的键,即 status
。
所以:
const modulesLens = lensProp('modules')
const resultsLens = lensProp('results')
const issuesLens = lensProp('issues')
const statusLens = lensProp('status')
现在,有了这些,您所要做的就是将它们放在一起。 (为了便于理解,我把它们分解了)
const approveIssues = over(
modulesLens,
map(over(
resultsLens,
map(over(
issuesLens,
map(set(statusLens, 'approve'))
))
))
)
现在剩下要做的就是向 approvedIssues
提供您要转换的数据,这就是我们的 data
。
所以,终于。
//Running this
const approvedData = approveIssues(data)
/* Outputs this
{
"id": 123,
"modules": [{
"id": 1,
"results": [{
"issues": [
{"data": {}, "status": "approve", "type": "change"},
{"data": {}, "status": "approve", "type": "remove"},
{"data": {}, "status": "approve", "type": "change"}
],
"status": "fail"
}]}, {
"id": 2,
"results": [{
"issues": [
{"data": {}, "status": "approve", "type": "change"},
{"data": {}, "status": "approve", "type": "remove"},
{"data": {}, "status": "approve", "type": "change"}],
"status": "pass"
}]}
]}
*/
在那种情况下我不一定要使用 compose
,但我想那也是可能的。
我觉得你更新的解决方案很好,但可以通过组合创建转换函数:
// update$modules$results$issues$status :: (String -> String) -> Object -> Object
var update$modules$results$issues$status = R.compose(
R.over(R.lensProp('modules')),
R.map,
R.over(R.lensProp('results')),
R.map,
R.over(R.lensProp('issues')),
R.map,
R.over(R.lensProp('status'))
);
update$modules$results$issues$status(R.always('approve'))(data);
我目前的数据结构大致如下所示:
var data = { "id": 123,
"modules": [{
"id": 1,
"results": [{
"status": "fail",
"issues": [
{"type": "change", "status": "warn", "data": {}},
{"type": "remove", "status": "warn", "data": {}},
{"type": "change", "status": "warn", "data": {}}
]
}]
},{
"id": 2
"results": [{
"status": "pass",
"issues": [
{"type": "change", "status": "warn", "data": {}},
{"type": "remove", "status": "warn", "data": {}},
{"type": "change", "status": "warn", "data": {}}
]
}]
}]
}
我一直在尝试使用 Ramda 来编写一个组合查询,它可以执行类似的操作,更改特定类型的所有问题的状态。
我一直在尝试按照通过 R.map/R.chain 组合镜头的方式做一些事情,但我似乎无法解决。我正在尝试做这样的事情:
let approvedData = R.compose(
R.set(R.__, 'approve', Data)
R.lensProp('status')
R.map(R.lensIndex),
R.lensProp('issues'),
R.map(R.lensIndex),
R.lensProp('results'),
R.map(R.lensIndex),
R.lensProp('modules')
)(Data)
并让它 return 返回状态已更改的完整数据集。
更新:
我已经想出了一些代码来完成我想做的事情,但我仍在努力将每个步骤变成可以组合的函数:
R.over(R.lensProp('modules'), R.map(
R.over(R.lensProp('results'), R.map(
R.over(R.lensProp('issues'), R.map(
R.set(R.lensProp('status'), 'approve')
))
))
), Data)
看来您可能对数组内值的转换有疑问。
现在,数据为
const data = {
"id": 123,
"modules": [{
"id": 1,
"results": [{
"status": "fail",
"issues": [
{"type": "change", "status": "warn", "data": {}},
{"type": "remove", "status": "warn", "data": {}},
{"type": "change", "status": "warn", "data": {}}
]
}]
},{
"id": 2,
"results": [{
"status": "pass",
"issues": [
{"type": "change", "status": "warn", "data": {}},
{"type": "remove", "status": "warn", "data": {}},
{"type": "change", "status": "warn", "data": {}}
]
}]
}]
};
您要做的是为包含数组的每个键创建透镜。在您的具体情况下,它们是 modules
、results
和 issues
.
最重要的是,您需要一个镜头到您想要修改的键,即 status
。
所以:
const modulesLens = lensProp('modules')
const resultsLens = lensProp('results')
const issuesLens = lensProp('issues')
const statusLens = lensProp('status')
现在,有了这些,您所要做的就是将它们放在一起。 (为了便于理解,我把它们分解了)
const approveIssues = over(
modulesLens,
map(over(
resultsLens,
map(over(
issuesLens,
map(set(statusLens, 'approve'))
))
))
)
现在剩下要做的就是向 approvedIssues
提供您要转换的数据,这就是我们的 data
。
所以,终于。
//Running this
const approvedData = approveIssues(data)
/* Outputs this
{
"id": 123,
"modules": [{
"id": 1,
"results": [{
"issues": [
{"data": {}, "status": "approve", "type": "change"},
{"data": {}, "status": "approve", "type": "remove"},
{"data": {}, "status": "approve", "type": "change"}
],
"status": "fail"
}]}, {
"id": 2,
"results": [{
"issues": [
{"data": {}, "status": "approve", "type": "change"},
{"data": {}, "status": "approve", "type": "remove"},
{"data": {}, "status": "approve", "type": "change"}],
"status": "pass"
}]}
]}
*/
在那种情况下我不一定要使用 compose
,但我想那也是可能的。
我觉得你更新的解决方案很好,但可以通过组合创建转换函数:
// update$modules$results$issues$status :: (String -> String) -> Object -> Object
var update$modules$results$issues$status = R.compose(
R.over(R.lensProp('modules')),
R.map,
R.over(R.lensProp('results')),
R.map,
R.over(R.lensProp('issues')),
R.map,
R.over(R.lensProp('status'))
);
update$modules$results$issues$status(R.always('approve'))(data);