ruby中有{x}速记吗?
我经常使用ruby中有{x}速记吗?,ruby,Ruby,我经常使用.group_by{x | x}和.find{x | x} 后者是在数组中查找第一个为真的项。 目前我只是在使用.compact。首先,但我觉得必须有一种优雅的方式来使用find here,比如find(&:to bool)或.find(true),我缺少的。 使用.find(&:nil?可以工作,但与我想要的正好相反,我找不到与#find或#detect相反的方法,或者像#true 那么,有没有更优雅的方式来编写。查找{x | x}?如果没有,我将坚持使用.compact.first
.group_by{x | x}
和.find{x | x}
后者是在数组中查找第一个为真的项。目前我只是在使用
.compact。首先
,但我觉得必须有一种优雅的方式来使用find here,比如find(&:to bool)
或.find(true)
,我缺少的。使用
.find(&:nil?
可以工作,但与我想要的正好相反,我找不到与#find或#detect相反的方法,或者像#true
那么,有没有更优雅的方式来编写。查找{x | x}
?如果没有,我将坚持使用.compact.first
(我知道compact不会删除
false
,但这对我来说不是问题,也请避免使用rails方法)
编辑:就我的具体情况而言,它仅用于字符串和零的数组,例如[nil,“x”,nil,nil,nil,nil,“y”,nil,nil,nil,nil,nil]
=>“x”可能是您在寻找的,这更具语义:
array.detect { |x| x }
出于好奇,monkeypatch:
class ::Object
def not_pure?
!!self
end
end
array.detect &:not_pure?
没有
如果在没有障碍物的情况下工作,您可以:
array.detect(&:tap)
array.detect(&:!)
但事实并非如此。不管怎样,我认为您所拥有的都是非常简洁、惯用的,并且恰好与上述非工作选项的字符数相同,因此您应该坚持:
array.compact.first
你可以通过修补程序来获得一个较短的版本,但是对于其他熟悉Ruby的人来说,这就变得不清楚了,因为这可能不值得一点点的“节省”
好奇的是,如果您碰巧想要array.detect{x |!x}
(相反),您可以执行以下操作:
array.detect(&:tap)
array.detect(&:!)
这是因为
!x实际上是x的缩写代码>。当然,这只会给您提供nil
或false
,这可能不是很有用。如果您不关心返回的内容,有时可以使用哈希方法
然而,您所要求的功能在Ruby中还不可用。它出现在Ruby路线图中:
预计在2035年12月25日前实施,你能等一下吗
也就是说,按{x{x}
分组需要多少打字
编辑:
正如Stefan所指出的,自从引入了对象本身以来,我的答案现在对Ruby 2.2及以上版本不再有效了。我个人有一个实用程序库,我把它包含在我所有的项目中
IDENTITIY = -> x { x }
那你会的
.group_by(&IDENTITY)
还有一个Object#本身
,它只返回self
:
.group_by(&:itself)
尽管标签是针对ruby
——使用Rails(更具体地说是ActiveSupport),您会得到一个方法presence
,它将适用于任何对present?
做出积极响应的方法(这将排除空白字符串、数组、哈希等):
它并不完全等同于首选结果,但它适用于我遇到的大多数情况。我经常使用group\u by、map、select、sort\u by和其他各种散列方法。昨天,我在一个类似的问题上反复尝试另一个答案,发现了这个有用的小扩展:
class Hash
def method_missing(n)
if has_key? n
self[n]
else
raise NoMethodError
end
end
end
对于任何由ruby创建的哈希,或者任何已由as_json进行jsonified的数据,这个添加允许我编写稍微短一点的代码。例如:
# make yellow cells
yellow = red = false
tube_steps_status.group_by(&:step_ordinal).each do |type|
group = type.last.select(&:completed).sort_by(&:completed)
red = true if group.last.step_status == 'red' if group.any?
yellow = true if group.map(&:step_status).include?('red')
end
tube_summary_status = 'yellow' if yellow unless red
我真的不知道你想要什么样的速记<代码>{| x | x}
不够短吗?经过一段时间后,试图缩短代码会适得其反。我总是在这里使用较长的选项,.compact.first
。我想你是对的,只是ruby通常有一种很好的方法来处理这样的事情,我想我忽略了一种。这有点像黑客,但我认为(&:dup)
适用于可变对象。例如:%w[a b a d b].group_by(&:dup)=>{“a”=>[“a”,“a”],“b”=>[“b”,“b”],“d”=>[“d”]}
。我读到了Ruby的一些计划,可以很好地做到这一点。@CarySwoveland复制每个元素可能有点昂贵。总是有ident=lambda{x}
和groupby(&ident)
,但这有点毫无意义,除非,您有一大串方法调用,并且已经将逻辑分解为lambda。#detect是#find的别名-我只是在寻找一种较短的方法来实现这一点,但在最坏的情况下,它会……)@user21033168 detect不是别名,它将Proc
实例作为参数;但我明白你的意思。@mudasobwa find也需要一个过程,它们只是别名。至少在ruby 2中。0@user21033168好啊我用一个愚蠢的monkeypatch更新了一个答案。array.detect(&:tap)
givesLocalJumpError:no block gived
该死,我以为你破解了它,但不幸的是,我得到了tap:no block gived(LocalJumpError)
这就是我写答案而不在深夜运行它的结果。哦,好吧。不过,我在回答中的最后一句话仍然有效:compact.first
的字符数是相同的,我认为不会比core Ruby短。你可以使用monkey patch,但它不太地道,可能不值得。为了给评论阅读时间,我会在某个时候删除这个答案。@Andrew Marshall即使.find(&:tap)
有效,.compact.first
的速度实际上是原来的两倍,这让我非常惊讶。(我对.find{x | x}
vs.compact.first
)进行了基准测试。是的,我认为.compact。首先,
仍然是最好的方法,除非有人能提出一个像您这样的简短优雅的解决方案。@user21033168我放弃了删除我的答案,而是果断地说,您想要的东西目前没有速记,您应该坚持使用:)
。好消息。我将倒计时,正好还剩8000天。第一句话非常重要,因为nil.hash
&false.hash
返回数字