You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Ramda函数组合实践:实现无点式关联cost属性至目标对象

实现无点式的成本关联函数(Ramda)

很高兴看到你在深挖Ramda和函数式编程的核心概念!把零散的操作整合成**无点式(Point-free)**的组合函数,确实是函数式风格的精华所在。我来帮你梳理出优雅的实现方案:

核心思路拆解

我们的目标是:给一个目标对象(比如aaa),自动从kdlJsonObj中匹配对应name的项,取出cost并关联到目标对象上,全程用组合式的写法完成,不需要显式声明参数。

这里的关键是:我们需要同时用到原目标对象从目标对象推导出来的cost值,所以单纯的compose/pipe不足以处理双输入的场景,Ramda的converge函数正好能解决这个问题——它可以让我们从同一个输入衍生出多个值,再传给合并函数。

完整实现代码

// API返回的对象
const kdlJsonObj = [ 
  {name: 'AAA COOPER TRANSPORTATION', cost: 33}, 
  {name: 'OLD DOMINION FREIGHT LINE, INC', cost: 22}, 
  {name: 'ROADRUNNER TRANSPORTATION SERVICES', cost: 31} 
]
// 待关联的目标对象
const aaa = {shortName: 'AAA Cooper', name: 'AAA COOPER TRANSPORTATION' }
const odlf = {shortName: 'Old Dominion', name: 'OLD DOMINION FREIGHT LINE, INC'}
const rr = {shortName: 'Road Runner', name: 'ROADRUNNER TRANSPORTATION SERVICES'}

// 定义无点式的组合函数
const addCostFromKdl = R.converge(
  // 合并函数:把cost关联到原对象上
  R.assoc('cost'),
  [
    // 分支1:从目标对象推导cost的流程(用pipe更符合阅读顺序)
    R.pipe(
      R.prop('name'), // 取出目标对象的name
      R.propEq('name'), // 创建匹配name的断言函数
      R.find(R.__, kdlJsonObj), // 用断言在kdl数组中找匹配项(R.__是占位符)
      R.prop('cost') // 取出匹配项的cost
    ),
    // 分支2:直接返回原目标对象(R.identity就是返回输入本身)
    R.identity
  ]
)

// 调用测试
addCostFromKdl(aaa) // => {shortName: "AAA Cooper", name: "AAA COOPER TRANSPORTATION", cost: 33}
addCostFromKdl(odlf) // => {shortName: "Old Dominion", name: "OLD DOMINION FREIGHT LINE, INC", cost: 22}
addCostFromKdl(rr) // => {shortName: "Road Runner", name: "ROADRUNNER TRANSPORTATION SERVICES", cost: 31}

代码解释

  1. R.converge的作用:它接收两个参数——一个合并函数,和一个函数数组。数组里的每个函数都会接收同一个输入(这里就是目标对象),然后把各自的结果传给合并函数。
  2. 分支1的pipe流程:从左到右执行,完全贴合我们的思考逻辑,而且全程是无点式的,没有显式声明参数。
  3. R.__占位符:用来告诉Ramda,我们要延迟传递某个参数,这里就是把find的断言参数留到pipe的前一步生成后再传入。

拓展:让函数更通用

如果以后需要切换不同的API数据源,可以把kdlJsonObj变成参数,让函数复用性更强:

const createCostAdder = (kdlData) => R.converge(
  R.assoc('cost'),
  [
    R.pipe(
      R.prop('name'),
      R.propEq('name'),
      R.find(R.__, kdlData),
      R.prop('cost')
    ),
    R.identity
  ]
)

// 用不同数据源生成对应的关联函数
const addCostFromKdl = createCostAdder(kdlJsonObj)
const addCostFromAnotherSource = createCostAdder(anotherKdlData)

你原来尝试的问题点

你之前在compose里写R.find(name, kdlJsonObj)是行不通的,因为compose要求每个中间函数都是一元函数(只接收一个参数),而R.find是二元函数(需要断言和数组)。用R.__占位符或者curry化之后,才能把它适配成一元函数的形式。

内容的提问来源于stack exchange,提问作者nzaleski

火山引擎 最新活动