2017-04-17 39 views
2

我注意到,如果我使用ramda有时我试图为我输出的方法编写Jest测试时出现问题。我在下面的测试和两个基本的减速机功能中解决了问题。我已经在gist上发布了它们,以便不会用代码堵塞这个问题。如果使用拉姆达减少但通过本机通过测试失败

https://gist.github.com/beardedtim/99aabe3b08ba58037b20d65343ed9d20

我获得与ramda减速以下错误:

 ● counter usage › counter counts the words and their index in the given list of words 

    expect(received).toEqual(expected) 

    Expected value to equal: 
     [{"count": 3, "indexes": [0, 2, 4], "value": "a"}, {"count": 1, "indexes": [1], "value": "b"}, {"count": 1, "indexes": [3], "value": "c"}] 
    Received: 
     [{"count": 15, "indexes": [0, 2, 4, 0, 2, 4, 0, 2, 4, 0, 2, 4, 0, 2, 4], "value": "a"}, {"count": 5, "indexes": [1, 1, 1, 1, 1], "value": "b"}, {"count": 5, "indexes": [3, 3, 3, 3, 3 
], "value": "c"}] 

这使我相信,ramda的减少是保持某种状态或分享words对方。我不确定这是如何发生的。任何人都知道我应该使用Google搜索或者处理此问题的其他人的文档/示例?

+0

这看起来像为数组的'reduce'实现https://github.com/ramda/ramda/blob/master/src/internal/_reduce.js#L7-L19 – elclanrs

+0

@elclanrs感谢您指出'减少'不需要索引。由于某些原因,添加索引不会改变我的测试仍然失败。我已经更新了要点来反映这一点。 –

回答

3

状态阵列(final)被硬连线到reduceWithIndex。所有对此功能的调用共享相同的final阵列。

试试这个:

import { reduce, addIndex } from 'ramda'; 

const reduceWithIndex = addIndex(reduce)((final, word, index) => { 
    const found = final.find(({ value }) => 
    value.toLowerCase() === word.toLowerCase() 
); 
    if (found) { 
    found.count++; 
    found.indexes.push(index); 
    } else { 
    final.push({ 
     value: word.toLocaleLowerCase(), 
     count: 1, 
     indexes: [index], 
    }); 
    } 

    return final; 
}); 

export default words => reduceWithIndex([], words); 
1

托马斯诊断通过点上。不过,我会选择一个稍微不同的解决办法:

import { reduce, addIndex, append } from 'ramda'; 

const reduceWithIndex = addIndex(reduce); 

export default reduceWithIndex((final, word, index) => { 
    const found = final.find(({ value }) => 
    value.toLowerCase() === word.toLowerCase() 
); 
    if (found) { 
    found.count++; 
    found.indexes.push(index); 
    return final; 
    } 
    return append({ 
     value: word.toLocaleLowerCase(), 
     count: 1, 
     indexes: [index], 
    }, final); 
}, []); 

函数式编程的内容很多,但最重要的问题之一是不可变的数据结构。尽管没有什么能够阻止你对累加器对象进行变异并将其传递回你的reducer函数,但我发现它的风格很差。相反,总是返回一个新的对象,你不会有这样的问题。所有拉姆达的功能都是建立在这个原则之上的,所以当使用append时,你会自动获得一个新的列表。

我还建议更改if -block以避免found对象的内部突变。我会把它作为一个练习,但如果难以做到,可以随时ping。

你可以看到original solution并在Ramda REPL的altered version之间的差异。

相关问题