问题描述
假设遵循对象,在给定的应用程序,标准ID和数据的条件下,如何使用Ramda在标准中执行嵌套更新?
const application = {
id: 'a1',
features: [
{
id: 'f1',
criterias: [
{ id: 'c1' }
]
},
{
id: 'f2',
criterias: [
{ id: 'c2' },
{ id: 'c3' }
]
}
]
}
该函数将如下所示:
const updateCriteria = (application, criteriaId, data) => // magic...
updateCriteria(application, 'c2', { name: 'foo' })
// output: {
// id: 'a1',
// features: [
// {
// id: 'f1',
// criterias: [
// { id: 'c1' }
// ]
// },
// {
// id: 'f2',
// criterias: [
// { id: 'c2', name: 'foo' },
// { id: 'c3' }
// ]
// }
// ]
// }
1楼
Scott Sauyet
4
已采纳
2019-02-21 16:01:11
镜头可能是您最好的选择。 Ramda具有通用的函数,并具有对象属性( ),数组索引( )和更深的path( )的 ,但不包括通过以下方法在数组中查找匹配值的函数: ID。 但是,制造我们自己并不难。
通过将两个函数传递给lens
来制作lens
:一个获取对象并获取相应值的吸气剂,以及获取新值和对象并返回对象的更新版本的设定器。
在这里,我们编写lensMatch
,它在给定属性名称与提供的值匹配的数组中查找或设置值。
lensId
只是将'id'
传递给lensMatch
以获取一个函数,该函数将获取id值并返回一个镜头。
使用任何镜头,我们都有 , 和函数,分别获取,设置和更新值。
我们可以这样使用idLens
:
const data = [{id: 'a'}, {id: 'b'}, {id: 'c'}]
view (idLens ('b'), data)
//=> {id: 'b'}
set (idLens ('b'), 'foo', data)
//=> [ {id: 'a'}, 'foo', {id: 'c'} ]
over (idLens ('b'), merge ({name: 'foo'}), data)
//=> [ {id: 'a'}, {id: 'b', name: 'foo}, {id: 'c'} ]
因此,对于您的问题,我们可以这样写:
const lensMatch = (propName) => (key) => lens ( find ( propEq (propName, key) ) , (val, arr, idx = findIndex (propEq (propName, key), arr)) => update (idx > -1 ? idx : length (arr), val, arr) ) const lensId = lensMatch ('id') const updateCriteria = (featureId, criteriaId, data, application) => over ( compose ( lensProp ('features') , lensId (featureId) , lensProp ('criterias') , lensId (criteriaId) ) , merge (data) , application ) const application = {id: 'a1', features: [{id: 'f1', criterias: [{ id: 'c1' }]}, {id: 'f2', criterias: [{ id: 'c2' }, { id: 'c3' }]}]} const newApp = updateCriteria ('f2', 'c2', {name: 'foo'}, application) console.log(newApp)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script> <script> const {lens, find, propEq, findIndex, update, length, view, set, over, compose, lensProp, merge} = R </script>
但这前提是您知道featureId
。
如果您需要同时找到featureId
和带有内部ID的嵌套对象,则可以为此编写一个更复杂的镜头,但重量会更大。
一个小注释:“标准”已经是复数形式,因此“标准”很奇怪。 单数是“标准”。