ramda js使用reduce连接值

时间:2019-02-10 16:15:39

标签: javascript functional-programming ramda.js

我有一个数据数组,该数据将转换为字符串。我已经创建了执行转换的功能。我的问题是编写此函数以使其更具可读性的最佳方法是什么?我不想有多个if/else语句。

const data = [
    "hello",
    {name: "Bob"},
    "and",
    {name: "Fred"},
    "How are you guys today?",
]

const isString = R.is(String)
const isObject = R.is(Object)

const getName = R.prop('name')

const toPureString = R.reduce(
    (result, value) => {
        if (isString(value)) {
            return `${result}${value} `
        }
        if (isObject(value)) {
            return `${result}${getName(value)}`
        } 
        return result
    }, "")

toPureString(data)
// hello Bob and Fred How are you guys today?

4 个答案:

答案 0 :(得分:2)

我会做这样的事情:

const {compose, join, map, unless, is, prop} = R
const data = ['hello', {name: 'Bob'}, 'and', {name: 'Fred'}, 'How are you guys today?']

const transform = compose(join(' '), map(unless(is(String), prop('name'))))

console.log(transform(data))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

unless是简化的if-else,除非谓词返回true,否则它返回原始值,在这种情况下,它将首先应用转换函数。 (when相似,不同之处在于它在谓词为true时应用转换)因此,此过程分两步进行,首先将所有内容转换为一致的格式,纯字符串,然后进行组合他们。

这可能对您来说更好看,但它们完全等效:

const transform = pipe(
  map(unless(is(String), prop('name'))),
  join(' '), 
)

答案 1 :(得分:1)

您可以使用R.cond

const { flip, is, unapply, join, useWith, prop, T, identity } = R

const isString = flip(is(String))
const isObject = flip(is(Object))
const spacer = unapply(join(' '))
const getName = useWith(spacer, [identity, prop('name')])

const toPureString = R.reduce(R.cond([
  [isString, spacer],
  [isObject, getName],
  [T, identity]
]), '')

const data = [
    "hello",
    {name: "Bob"},
    "and",
    {name: "Fred"},
    "How are you guys today?",
]

const result = toPureString(data)

console.log(result) // hello Bob and Fred How are you guys today?
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

答案 2 :(得分:0)

Ramda具有ifElse功能。但是,当您有多个分支到if语句时,它将变得很笨拙:

const ifStr = R.ifElse(isString, v => `{result}{v}`, () => result);
return R.ifElse(isObject, v => `{result}{getName(v)}`, ifStr);

在这种情况下,我将使用纯JavaScript中的三元语句来做到这一点:

const toPureString = R.reduce((result, value) => {
    const str = isObject(value) ? getName(value) : (isString(value) ? value : '')
    return `${result}${str}`
}, '')

答案 3 :(得分:0)

const data = ["hello",{name: "Bob"},"and",{name: "Fred"},"How are you guys today?"]

function getValue(val){
 return typeof val ==='string'? val : val.name; 
} 

let res = data.reduce((a,b)=> a.concat(' ', getValue(b)))
console.log(res)