在 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 的方式也将被认为是这个问题的答案。
不太确定您在寻找什么,但是:
剧透警告 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 "
您还可以使用
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 "
您可以使用 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 的创建者和维护者
与其他人略有不同,但我喜欢
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 <>"