基于对象中某些值的 Ramda 镜头
Ramda lenses based on a some value in object
社区,您好。我遇到了一个小问题。
我有这样一个数据结构
{
"type": "Shoes",
"gender": "female",
"userInfo": {
"whois": {
"male": {
"htt": 20.2,
"referenceBrands": [{
"category": "Shoes",
"size": 40
}]
},
"female": {
"height": 191.0,
"age": 20,
"referenceBrands": [{
"category": "Shoes",
"size": 35.5
}, {
"category": "Apparel",
"size": 50
}]
}
},
}
}
我想根据根中的 gender
和 type
更新参考品牌中的特定密钥。
基于此 (感谢 Scott Sauyet),我创建了类似的东西。但是如您所见,我已经对 gender
和 category
进行了硬编码,使用组合和无点样式来更改此设置的最佳方法是什么?
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 lensCategory = lensMatch('category')
const genderLens = lensProp('gender')
const lensReferenceBrand = lensProp('referenceBrands')
const updateSize = (prop, value) => over(
compose(
lensPath(['userInfo', 'whois']),
lensProp('female'),
lensReferenceBrand,
lensCategory('Shoes'),
lensProp(prop),
), always(value), data)
updateSize('size', 100)
我可能会这样写:
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 updateSize = (prop, value, gender, category, data) =>
set
( compose
( lensPath (['userInfo', 'whois', gender, 'referenceBrands'])
, lensMatch ('category') (category)
, lensProp (prop)
)
, value
, data
)
const data = {type: "Shoes", gender: "female", userInfo: {whois: {male: {htt: 20.2, referenceBrands: [{category: "Shoes", size: 40}]}, female: {height: 191, age: 20, referenceBrands: [{category: "Shoes", size: 35.5}, {category: "Apparel", size: 50}]}}}};
console .log (
updateSize ('size', 100, 'female', 'Shoes', data)
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script>const {lens, find, findIndex, propEq, update, length, set, compose, lensPath, lensProp} = R </script>
请注意,我将 over
替换为 set
。 over
是关于通过将函数应用于旧值来创建新值,set
只是将其设置为给定值。这意味着我也可以删除多余的 always
。
当然你也可以使用
( compose
( lensPath (['userInfo', 'whois'])
, lensProp (gender)
, lensProp ('referenceBrands')
, lensMatch ('category') (category)
, lensProp (prop)
)
甚至将 lensPath
分成两个 lensProp
,但我看不出有什么理由。
这远非毫无意义。事实上,主函数有五个命名参数,比我通常习惯的多两个,比我喜欢的多四个。但它们似乎都是必要的。而且我只有在提高可读性时才选择无点。我怀疑无点解决方案会使情况变得更糟。
我不知道这个部分应用的版本是否有帮助,但将签名更改为
会很容易
const updateSize = (prop, value) => (gender, category) => (data) => ...
// ...
updateSize ('size', 100) ('female', 'Shoes') (data)
或类似的,或使用 R.curry
。
社区,您好。我遇到了一个小问题。 我有这样一个数据结构
{
"type": "Shoes",
"gender": "female",
"userInfo": {
"whois": {
"male": {
"htt": 20.2,
"referenceBrands": [{
"category": "Shoes",
"size": 40
}]
},
"female": {
"height": 191.0,
"age": 20,
"referenceBrands": [{
"category": "Shoes",
"size": 35.5
}, {
"category": "Apparel",
"size": 50
}]
}
},
}
}
我想根据根中的 gender
和 type
更新参考品牌中的特定密钥。
基于此 gender
和 category
进行了硬编码,使用组合和无点样式来更改此设置的最佳方法是什么?
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 lensCategory = lensMatch('category')
const genderLens = lensProp('gender')
const lensReferenceBrand = lensProp('referenceBrands')
const updateSize = (prop, value) => over(
compose(
lensPath(['userInfo', 'whois']),
lensProp('female'),
lensReferenceBrand,
lensCategory('Shoes'),
lensProp(prop),
), always(value), data)
updateSize('size', 100)
我可能会这样写:
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 updateSize = (prop, value, gender, category, data) =>
set
( compose
( lensPath (['userInfo', 'whois', gender, 'referenceBrands'])
, lensMatch ('category') (category)
, lensProp (prop)
)
, value
, data
)
const data = {type: "Shoes", gender: "female", userInfo: {whois: {male: {htt: 20.2, referenceBrands: [{category: "Shoes", size: 40}]}, female: {height: 191, age: 20, referenceBrands: [{category: "Shoes", size: 35.5}, {category: "Apparel", size: 50}]}}}};
console .log (
updateSize ('size', 100, 'female', 'Shoes', data)
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script>const {lens, find, findIndex, propEq, update, length, set, compose, lensPath, lensProp} = R </script>
请注意,我将 over
替换为 set
。 over
是关于通过将函数应用于旧值来创建新值,set
只是将其设置为给定值。这意味着我也可以删除多余的 always
。
当然你也可以使用
( compose
( lensPath (['userInfo', 'whois'])
, lensProp (gender)
, lensProp ('referenceBrands')
, lensMatch ('category') (category)
, lensProp (prop)
)
甚至将 lensPath
分成两个 lensProp
,但我看不出有什么理由。
这远非毫无意义。事实上,主函数有五个命名参数,比我通常习惯的多两个,比我喜欢的多四个。但它们似乎都是必要的。而且我只有在提高可读性时才选择无点。我怀疑无点解决方案会使情况变得更糟。
我不知道这个部分应用的版本是否有帮助,但将签名更改为
会很容易const updateSize = (prop, value) => (gender, category) => (data) => ...
// ...
updateSize ('size', 100) ('female', 'Shoes') (data)
或类似的,或使用 R.curry
。