地图,在朱莉娅中用`|>`减少

map, reduce with `|>` in julia

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

用法示例

2 |> log |> sqrt 

对我来说,这比 sqrt(log(2)) 好看多了。特别是当链条变得很长时。我想将此语法用于 Julia 中的 mapreduce 类型的函数。

设置

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 中,mapping/filter 函数位于可迭代对象之前。 R 会通过给你一个你可以使用的中缀 . 来解决这个问题,在这种情况下,语法看起来更像:

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

在 Julia 中可以实现这样的功能吗? |> 运算符有可能将长链代码清理成整洁的操作管道。解决问题的一种可能更像 Julia-thonic 的方式也将被视为该问题的答案。

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

剧透警告 8-)

julia> trans |> 
         t -> filter(x -> isalpha(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 <>"