加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 为什么Hash #select和Hash#reject将密钥传递给一元块?

发布时间:2020-12-17 03:29:02 所属栏目:百科 来源:网络整理
导读:我的理解是Hash #select和Hash#reject每次传递一个键数组及其值[key,value]作为每个迭代的单个块参数,你可以使用隐式破坏性赋值直接在块中选择它们: {a: 1,b: 2}.select{|k,v| k == :a} # = {:a = 1}{a: 1,b: 2}.reject{|k,v| v == 1} # = {:b = 2} 或明确
我的理解是Hash #select和Hash#reject每次传递一个键数组及其值[key,value]作为每个迭代的单个块参数,你可以使用隐式破坏性赋值直接在块中选择它们:

{a: 1,b: 2}.select{|k,v| k == :a} # => {:a => 1}
{a: 1,b: 2}.reject{|k,v| v == 1} # => {:b => 2}

或明确的破坏性赋值:

{a: 1,b: 2}.select{|(k,v)| k == :a} # => {:a => 1}

我预计,当我传递一个一元块时,整个[key,value]数组将被传递,但实际上,似乎键被传递:

{a: 1}.select{|e| p e} # => Prints `:a`  (I expected `[:a,1]`)

为什么这样工作?对于像map这样的其他Hash实例方法,传递整个[key,value]数组.

如果它特别设计为与二进制块相比对一元块的工作方式不同,那么我可以理解它是有用的.但是,我不明白为什么上面用明确的破坏性赋值的情况就是这样的.而且我也没有找到任何提及此类规范的文件.

编辑我对{a:1,b:2} .reject {|(k,v)|的结果有误v == 1}.在此更正:

{a: 1,b: 2}.reject{|(k,v)| v == 1} # => {:a=>1,:b=>2} (not `{:b=>2}`)

现在,这也表明(k,v)是关键,而不是[key,value],因此v总是为零.参看DarekN?dza的评论.

解决方法

它总是传递两个参数.

你所观察到的仅仅是触发器和lambdas如何处理多余论点之间的区别.块(Procs除非你告诉Ruby否则)表现得好像它有一个额外的splat并丢弃多余的参数,而lambdas(和方法对象)由于不正确的arity而拒绝调用者.

示范:

>> p = proc { |e| p e }
=> #<Proc:0x007f8dfa1c8b50@(irb):1>
>> l = lambda { |e| p e }
=> #<Proc:0x007f8dfa838620@(irb):2 (lambda)>
>> {a: 1}.select &p
:a
=> {:a=>1}
>> {a: 1}.select &l
ArgumentError: wrong number of arguments (2 for 1)
    from (irb):2:in `block in irb_binding'
    from (irb):4:in `select'
    from (irb):4
    from /usr/local/bin/irb:11:in `<main>'

顺便说一句,因为在评论中提到过:相反,map实际上传递了一个参数.它被分配给两个不同的变量,因为你可以在赋值运算符的右侧分配多个带有数组的变量,但它始终是一个参数.

示范:

>> {a: 1}.map { |k,v| p k,v }
:a
1
>> {a: 1}.map &p
[:a,1]
=> [[:a,1]]
>> {a: 1}.map &l
[:a,1]

并且在更改p和l时进一步定义:

>> p = proc { |k,v }
=> #<Proc:0x007ffd94089258@(irb):1>
>> l = lambda { |k,v }
=> #<Proc:0x007ffd940783e0@(irb):2 (lambda)>
>> {a: 1}.map &p
:a
1
=> [[:a,1]]
>> {a: 1}.map &l
ArgumentError: wrong number of arguments (1 for 2)
    from (irb):2:in `block in irb_binding'
    from (irb):4:in `each'
    from (irb):4:in `map'
    from (irb):4
    from /usr/local/bin/irb:11:in `<main>'

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读