坚持拉姆达组成

时间:2017-10-20 18:27:21

标签: javascript ramda.js

我正在尝试将以下输入转换为下面显示的预期输出JSON数组。 indexCols也是

var objects = ['{"ticker":"MSFT", "key": 2, "PX_LAST":100}',
               '{"ticker":"AAPL", "key": 3, "PX_LAST":100}',
               '{"ticker":"GOOG", "key": 4, "PX_LAST":100}']

/* Expected output
  [[id, '{"ticker":"MSFT",  "key": 2, "PX_LAST":100}', 'MSFT', 2 ]
    [id, '{"ticker":"AAPL", "key": 3, "PX_LAST":100}', 'AAPL', 3 ]
    [id, '{"ticker":"GOOG", "key": 4, "PX_LAST":100}', 'GOOG', 4 ]]
*/
var indexCols = ['ticker', 'key']

var transform = function(input, indexCols, id) {
  var fn2 = R.compose(R.flip(R.map)(indexCols), R.flip(R.prop), JSON.parse)
  var fn3 = R.map(R.compose(R.concat([id]), fn2))
  return fn3(objects)
}

transform(objects, indexCols, 100)
/* result : [[100, "MSFT", 2], [100, "AAPL", 3], [100, "GOOG", 4]] */

正如您所看到的,结果数组缺少第二个元素,即json字符串。我无法以功能性的方式编织它。

3 个答案:

答案 0 :(得分:1)

(我认为有一个拼写错误,而不是这个:返回fn3(对象)你可能是这个意思:return fn3(input))

  var transform = function(input, indexCols, id) {
      var fn2 = R.compose(R.flip(R.map)(indexCols), R.flip(R.prop), JSON.parse);
      var valueToArray = R.flip(R.append)([]);
      var fn3 = R.map(R.compose(R.flatten, R.concat([id]), R.compose(R.ap([R.identity, fn2]), valueToArray)))
      return fn3(input)
    }

https://codepen.io/anon/pen/Jrzmda

你必须复制你的输入对象(a-> [a,a]),然后你可以随意操作第二个元素(fn2),只保持第一个元素不变(标识),然后在最后,把它们连在一起。

改进1:valueToArray(a-> [a])是否已经存在Ramda函数? 改进2:有没有办法连接id 而不是嵌套来摆脱R.flatten?

答案 1 :(得分:1)

您可以使用R.converge,以便将字符串提供给concat和JSON.parse:

var objects = ['{"ticker":"MSFT", "key": 2, "PX_LAST":100}',
               '{"ticker":"AAPL", "key": 3, "PX_LAST":100}',
               '{"ticker":"GOOG", "key": 4, "PX_LAST":100}']

/* Expected output
  [[id, '{"ticker":"MSFT",  "key": 2, "PX_LAST":100}', 'MSFT', 2 ]
    [id, '{"ticker":"AAPL", "key": 3, "PX_LAST":100}', 'AAPL', 3 ]
    [id, '{"ticker":"GOOG", "key": 4, "PX_LAST":100}', 'GOOG', 4 ]]
*/
var indexCols = ['ticker', 'key']

var transform = function(input, indexCols, id) {
  //Have to trick R.converge into making it think that JSON.parse only has 1 argument
  var fn2 = R.compose(R.flip(R.map)(indexCols), R.flip(R.prop), R.curryN(1, JSON.parse))
  var fn3 = R.map(R.compose(R.concat([id]), R.converge(R.concat, [Array, fn2])))
  return fn3(input) //typo shouldn't be objects
}

console.log(transform(objects, indexCols, 100))
/* result : [[100, "MSFT", 2], [100, "AAPL", 3], [100, "GOOG", 4]] */
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

另一种方法是使用:

R.ap(R.compose(R.concat, Array), fn2))
// concat <$> Array <*> fn2
// R.liftN(2, R.concat)(Array, fn2) is the same

而不是:

R.converge(R.concat, [Array, fn2])

这样你就不会遇到R.converge问题,因为它猜测JSON.parse有2个参数。

答案 2 :(得分:0)

这些看起来不必要地复杂......

怎么样:

const objects = ['{"ticker":"MSFT", "key": 2, "PX_LAST":100}',
               '{"ticker":"AAPL", "key": 3, "PX_LAST":100}',
               '{"ticker":"GOOG", "key": 4, "PX_LAST":100}']
const indexCols = ['ticker', 'key', 'PX_LAST']

const pickIndeces = pipe(JSON.parse, props(indexCols))
const format = map(x => concat([x], pickIndeces(x)))
format(objects)

注意,pipepropsconcatmap是Ramda函数。所以你可以导入它们,如下所示:

const { concat, map, pipe, props } = R