Julia中的函数链

Julia中的函数链,julia,Julia,是否可以将多个函数调用编写为一个链 sum( map(parseIgFloat, map((row) -> row.PL_Amount, filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In", collect(ts) ) ) ) ) 把它变成这样: ts |> collect |> filter

是否可以将多个函数调用编写为一个链

sum(
  map(parseIgFloat, 
    map((row) -> row.PL_Amount, 
      filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In", 
        collect(ts)
      )
    )
  )
)
把它变成这样:

ts 
  |> collect
  |> filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In")
  |> map((row) -> row.PL_Amount)
  |> map(parseIgFloat)
  |> sum

经过搜索,这似乎是最好的选择

ts |> 
  collect |> 
  (list -> filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In", list)) |>
  (list -> map((row) -> row.PL_Amount, list)) |>
  (list -> map(parseIgFloat, list)) |>
  sum
或者使用带有宏的
管道

@pipe ts |> 
  collect |> 
  filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In", _) |>
  map((row) -> row.PL_Amount, _) |>
  map(parseIgFloat, _) |>
  sum

一般来说,您所要求的是困难的,因为无论您提出什么构造,您都必须保证传递的参数顺序是函数所期望的顺序,因此没有足够通用的方法允许您在不为其定义显式类型和操作的情况下执行此操作

然而,特别是对于
map
filter
,创建这些函数的“curried”版本并对其应用链接是很简单的。例如

#创建用于“链接”的地图和过滤器的通用版本
导入Base.map;功能图(f);返回L->map(f,L);结束;
导入Base.filter;函数滤波器(f);返回L->过滤器(f,L);结束;
f=x->x^2;
ts=范围(1,停止=10);
(ts
|>收集
|>地图(f)#将集合按正方形排列
|>过滤器(iseven)#只保留偶数结果
|>总数
)
输出:

220

PS:链接主要是为了易于阅读,当您有一系列单独的简单且直观的命令时,它最有用,如上所述。如果你的“链”中有复杂的表达式,比如你提出的解决方案中的表达式,那么在我看来,这并不值得。或者将复杂的表达式封装到适当命名的函数中,使链读起来像普通英语一样,或者首先避免链接,而是依赖使用临时变量的清晰步骤


PS2:还要注意,
|>
操作符与任何函数一样,也是广播的有效目标。因此,上面的map(f)也可以更简单地写成

我可能会这样写:

sum(row -> parseIgFloat(row.PL_Amount),
    filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In", 
            ts)
    )
sum(parseIgFloat(_.PL_Amount)), 
    filter(!ismissing(_.Summary) && _.Summary == "Cash In",  # actually not sure if this line would work
           ts)
    )
如果出现下划线咖喱(),可以将其简化为:

sum(row -> parseIgFloat(row.PL_Amount),
    filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In", 
            ts)
    )
sum(parseIgFloat(_.PL_Amount)), 
    filter(!ismissing(_.Summary) && _.Summary == "Cash In",  # actually not sure if this line would work
           ts)
    )
在这一点上,链接也可能变得更加方便


顺便说一句:不要使用
收集
,除非你真的不得不这样做。

当然。看看这个@JongsuLiamKim谢谢,但这不一样,这个问题的函数只有一个参数,而这里有两个函数,如带有多个参数的
filter
map
。我想找到一种最简洁、最好的方法来编写它。但是,请注意,这是:向
Base.map
添加不使用自己类型的新方法可能会与其他代码组合不好。@SGJ同意。这只是一个简单的例子,适当使用名称空间是可取的,等等,只要它不损害可读性。话虽如此,我假设这就是Stefan所指的,他说他可以设想少量标准的、预定义的curried函数(根据这里的另一个答案中的链接)。