如果使用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,謝謝你的糾正。我編輯過。 –