我知道Ramda有很多有用的功能,但我不知道,如何更好地组合它。任何人都可以做得更好吗? PS。一些人提到拉姆达的思考方式会很好。
// @flow
/**
const state = {
forms: [
{id: 'form-id'}
],
inputs: [
{inputId: 'input-id', formId: 'form-id', value: ''}
]
}
*/
import { propEq, find, update, compose, assoc, assocPath, findIndex } from 'ramda';
export const setInputValueInState = (
inputId: string,
value: string,
state: FormsState,
): FormsState => {
const input = getInputById(inputId, state);
const inputWithNewValue = assoc('value', value, input);
const inputIndex = findIndex(propEq('inputId', inputId))(state.inputs);
return assocPath(['inputs', inputIndex], inputWithNewValue, state);
};
答案 0 :(得分:2)
你有很多方法可以解决这个问题。通过巧妙地使用useWith
或converge
,您可以创建现有函数的无点版本。我不认为它最终会变得特别可读,所以我会考虑其他技术。
一种可能性是使用lenses
。镜头上的大多数文章都是针对Haskell或其他语言的。但我在A. Sharif,Drew Tipson和Vladimir Gorej
Ramda有几个内置镜头创建功能,lensProp
,lensPath
和lensIndex
,以及view
,set
等功能,和over
合作镜头。但创建属于您自己的内容非常容易,例如下面的inputIdLens
。
const state = {
forms: [
{id: 'form-id'}
],
inputs: [
{inputId: 'i-1', formId: 'foo-12', value: '123'},
{inputId: 'i-2', formId: 'bar-34', value: '234'},
{inputId: 'i-3', formId: 'baz-56', value: '345'},
{inputId: 'i-4', formId: 'qux-78', value: '456'},
{inputId: 'i-5', formId: 'corge-90', value: '567'}
]
}
const {lens, find, propEq, update, findIndex, set, compose, lensProp} = R
const inputIdLens = (inputId) => lens(
(s) => find(propEq('inputId', inputId), s),
(a, s) => update(findIndex(propEq('inputId', inputId), s), a, s)
)
const setInputValueInState = (inputId, val, state) =>
set(compose(lensProp('inputs'), inputIdLens(inputId), lensProp('value')), val, state)
console.log(setInputValueInState('i-2', 'foobar', state))

<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
&#13;
答案 1 :(得分:0)
尽管Scott的答案更具实用性,但我发现这种方法更易于编写和理解。与镜头相比,我更喜欢evolve
,感觉更自然的IMO。
import { curry, evolve, adjust, findIndex, propEq, assoc } from 'ramda';
const state = {
forms: [
{id: 'form-id'}
],
inputs: [
{inputId: 'i-1', formId: 'form-1', value: '123'},
{inputId: 'i-2', formId: 'form-2', value: '234'},
]
}
const setInputValueInState = curry((inputId, value, obj) => evolve({
inputs: adjust(
findIndex(propEq('inputId', inputId), obj.inputs),
assoc('value', value),
),
}, obj));
setInputValueInState('i-2', 'foobar', state);