如果使用Enumerable#map,则会返回一个数组,其中每个字符在字符串中都有一个元素。
arr = "try this".each_char.map.with_index { |c,i| i.even? ? c : nil }
#=> ["t", nil, "y", nil, "t", nil, "i", nil]
这是一样的
arr = "try this".each_char.map.with_index { |c,i| c if i.even? }
#=> ["t", nil, "y", nil, "t", nil, "i", nil]
我最初的答案使用Array#compact加盟之前删除nil
小号建议:
arr.compact.join
#=> "tyti"
但@npn笔记,compact
是没有必要的因为Array#join将NilClass.to_s应用于nil's
,将它们转换为空字符串秒。人机工程学,你可以简单地写
arr.join
#=> "tyti"
你可以使用map
是先申请Enumerable#each_cons通过对字符,然后返回每对的第一个字符的另一种方式:
"try this".each_char.each_cons(2).map(&:first).join
#=> "tyti"
即使如此,Array#select是优选的,因为它返回只有感兴趣的字符:
"try this".each_char.select.with_index { |c,i| i.even? }.join
#=> "tyti"
这方面的一个变体是:
even = [true, false].cycle
#=> #<Enumerator: [true, false]:cycle>
"try this".each_char.select { |c| even.next }.join
#=> "tyti"
它使用Array#cycle创建枚举和Enumerator#next以产生其元素。
一个小的事情:String#each_char是更多的内存效率比String#chars,因为前者返回的枚举,而后者产生一个临时数组。
通常,当接收器是一个数组,
我,我会用一个简单的正则表达式:
"Now is the time to have fun.".scan(/(.)./).join
#=> "Nwi h iet aefn"
我不认为你真的不需要在加入之前调用compact来从数组中删除nil。 #join,每个元素都有#to_s类,而NilClass有一个返回“”的to_s方法。所以我不认为这是依靠无证行为跳过.compact调用的情况。 – nPn
@nPn,谢谢你的纠正。我编辑过。 –