【问题标题】:map, reduce with `|>` in julia映射,在 julia 中使用 `|>` 减少
【发布时间】:2015-06-14 00:58:09
【问题描述】:

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

示例用法

2 |> log |> sqrt 

对我来说,这比sqrt(log(2)) 好得多。特别是当链条变得很长时。我想使用这种语法,但也想使用 Julia 中的 map,reduce-type 函数。

设置

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 中是否可能发生这样的事情? |&gt; 操作符有可能将长链代码清理成整洁的操作管道。一种可能更符合 Julia-thonic 的解决问题的方式也将被视为对这个问题的回答。

【问题讨论】:

  • 我发现链接和管道对于数据分析非常方便。将我们从所有的行首和添加另一个函数中,然后在行尾添加正确数量的右括号等。
  • @rickhg12hs 同意。当然,另一方面,就像你有一条带有多重嵌套函数调用的行一样,如果你依赖于多个链接/重定向,特别是涉及为实现重定向而创建的定制匿名函数,您可能会以离散的步骤编写代码,这样阅读起来会更清晰(更不用说,可以进行适当的评论)。但我同意,在嵌套和链接之间,链接在视觉上更令人愉悦。

标签: julia


【解决方案1】:

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

剧透警告 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 "

【讨论】:

    【解决方案2】:

    您还可以使用 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 "
    

    【讨论】:

    • 甚至,@&gt;&gt; trans filter(x -&gt; isalpha(x) || isspace(x)) map(x -&gt; d[x]) 对于这种情况。
    【解决方案3】:

    您可以使用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 的创建者和维护者

    【讨论】:

    • 这是我第二次看到有人创建 julia 包来解决语言或其他包的问题。另一个人写了TimeZonedDateTime 的东西,而不是修复std::DateTime,在这里,您创建了一个宏来克服这样一个事实,即该地图不能与开箱即用的链接一起工作,可能是因为currying 没有按预期工作。我开始看到一种模式……一种糟糕的模式。
    • 对我来说这听起来像是一个功能,而不是一个问题。
    • 这正是问题所在。人们看到做新事物比修复旧事物更荣耀。这将导致无数本可以避免的包裹。少即是多。
    【解决方案4】:

    和其他的略有不同,但我喜欢

    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 <>"
    

    【讨论】:

      猜你喜欢
      • 2016-01-22
      • 2015-03-16
      • 2018-08-14
      • 1970-01-01
      • 2012-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多