想在拉姆达

时间:2018-01-30 11:16:03

标签: ramda.js

我知道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);
};

2 个答案:

答案 0 :(得分:2)

你有很多方法可以解决这个问题。通过巧妙地使用useWithconverge,您可以创建现有函数的无点版本。我不认为它最终会变得特别可读,所以我会考虑其他技术。

一种可能性是使用lenses。镜头上的大多数文章都是针对Haskell或其他语言的。但我在A. SharifDrew TipsonVladimir Gorej

的Javascript中找到了一些内容

Ramda有几个内置镜头创建功能,lensProplensPathlensIndex,以及viewset等功能,和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;
&#13;
&#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);