RamdaJS:组合一个对象会产生相同的“随机”结果

时间:2015-10-30 13:55:46

标签: javascript functional-programming ramda.js

我正在和Ramda一起玩,试图让我了解功能性JS。以下代码尝试生成一些随机搜索过滤器对象:

var R = require('ramda');
var rWords = require('random-words');

var types = ['keyword', 'phrase', 'domain', 'person'];
var operands = ['AND', 'OR', 'NOT'];

var getRandom = (min=1, max=10) => Math.floor(Math.random() * (max - min)) + min;
var sample = (arr) => arr[getRandom(0, arr.length)];
var chooseWords = (min=1, max=getRandom()) => rWords({min, max, join: ' '});
var chooseWordsFromType = (obj) => {
    var max = obj.type === 'phrase' ? 10 : 1;
    query = chooseWords(1, max);
    return R.merge({query}, obj);
};

var makeFilter = R.compose(
    chooseWordsFromType,
    R.merge({operand: sample(operands)}),
    R.merge({type: sample(types)})
);

var initial = [];
for(var i = 0; i < getRandom(); i++){
    initial.push(makeFilter({}));
}
console.log(initial);

预期结果应该是

[
  {type: 'keyword', operand: 'AND', query:['something']},
  {type: 'domain', operand: 'AND', query:['something_else']}
]

错误是initial中的所有内容都具有完全相同的操作数和类型;只有查询本身不同。我想它会记住对sample的调用,但我不知道为什么。

顺便说一下,我如何重构chooseWordsFromType以便它能够在不需要返回对象的情况下进行组合?或者我可以吗?

1 个答案:

答案 0 :(得分:2)

您对此代码有何期待?:

var defaultOperands = {operand: sample(operands)};
var defaultTypess = {type: sample(types)};

var makeFilter = R.compose(
    chooseWordsFromType,
    R.merge({operand: defaultOperands}),
    R.merge({type: defaultTypes})
);

您的代码:

var makeFilter = R.compose(
    chooseWordsFromType,
    R.merge({operand: sample(operands)}),
    R.merge({type: sample(types)})
);

做了很多相同的事情,实质上说,&#34;调用sample,传入operands,从中创建一个对象,由&#39;操作数键入&#39; &#34;,执行与types和&#39;类型&#39;类似的操作,然后创建一个makeFilter函数,它将每个静态对象与您的输入合并,并返回结果将其传递给chooseWordsFromType

使其成为动态的一种(未经测试的)方式是:

var makeFilter = R.compose(
    chooseWordsFromType,
    obj => R.merge({operand: sample(operands)}, obj),
    obj => R.merge({type: sample(types)}, obj)
);