在 Julia 中使用 `|>` 进行映射、减少

问题描述 投票:0回答:4

在 R 中,使用

dyplr
可以使用
%>%
运算符,它允许您将函数的输出通过管道传输到新函数,从而无需存储中间值。在 Julia 中,您可以通过使用
|>
运算符来实现非常类似的效果。

使用示例

2 |> log |> sqrt 

对我来说,这读起来比

sqrt(log(2))
好得多。尤其是当链条变得很长时。我想使用这种语法,但也想在 Julia 中使用
map
reduce
类型的函数。

设置

from = "abcdefghijklmnopqrstuvwxyz"
to   = "cdefghijklmnopqrstuvwxyzab"
trans = "g fmnc wms bgblr rpylqjyrc gr zw fylb <>"
d = {from[i] => to[i] for i = 1:26}
d[' '] = ' '

什么有效

map(x -> d[x], filter(x -> isalpha(x) || isspace(x), trans))

这可行,但读起来并不像我希望的那样。另一种方法是将中间结果存储到变量中,但这似乎也很冗长:

res1 = filter(x -> isalpha(x) || isspace(x), trans)
map(x -> d[x], res1)

我想要什么

R 语法与此类似:

trans |> 
  filter(x -> isalpha(x) || isspace(x)) |> 
  map(x -> d[x])

这不起作用,因为在 Julia 中,映射/过滤函数位于可迭代之前。 R 会通过给你一个可以使用的中缀

.
来解决这个问题,在这种情况下,语法看起来更像是:

trans |> 
  filter(x -> isalpha(x) || isspace(x), .) |> 
  map(x -> d[x], .)

在 Julia 中可能发生这样的事情吗?

|>
运算符有潜力将长代码链清理成整齐的操作管道。解决这个问题的一种也许更 Julia-thonic 的方式也将被认为是这个问题的答案。

julia
4个回答
14
投票

不太确定您在寻找什么,但是:

剧透警告 8-)

julia> trans |> 
         t -> filter(x -> isletter(x) || isspace(x), t) |> 
         f -> map(x -> d[x],f)
"i hope you didnt translate it by hand "

7
投票

您还可以使用

Lazy
包中的 @as 宏来更接近您喜欢的形式:

julia> using Lazy

julia> @as _ trans begin
         filter(x -> isalpha(x) || isspace(x), _)
         map(x -> d[x], _)
       end
"i hope you didnt translate it by hand "

4
投票

您可以使用 Pipe.jl 包来执行以下操作:

@pipe trans |> filter(x -> isalpha(x) || isspace(x), _) |> map(x -> d[x], _)

或者

@pipe ( trans 
     |> filter(x -> isalpha(x) || isspace(x), _) 
     |> map(x -> d[x], _)
)

如果宏的参数有多行,则需要用括号括起来。

注意:我是 Pipe.jl 的创建者和维护者


0
投票

与其他人略有不同,但我喜欢

using Lazy

from = "abcdefghijklmnopqrstuvwxyz"
to   = "cdefghijklmnopqrstuvwxyzab"
trans = "g fmnc wms bgblr rpylqjyrc gr zw fylb <>"

dd = Dict(zip(from, to))
@>> trans map(t -> isletter(t) ? dd[t] : t)

产生

"i hope you didnt translate it by hand <>"
© www.soinside.com 2019 - 2024. All rights reserved.