2017-01-16 72 views
3

我有一個集合:如何使用Ruby集合函數從空行合併值?

a = [[1, "a"], [nil, "b"], [nil, "c"], [2, "a"], [nil, "b"]] 

[[1, "a"], 
[nil, "b"], 
[nil, "c"], 
[2, "a"], 
[nil, "b"]] 

,我想獲得:

[[1, "abc"], 
[2, "ab"]] 

什麼是Ruby來實現這一正確的方法?怎樣纔能有效地使用ruby內建的集合函數呢?

+1

這似乎是一個純Ruby問題,在這種情況下,不應該有Rails標記。請注意,有些讀者會過濾出具有某些標籤的問題,因此您不應該包含不必要的標籤。這裏我只需要一個標籤:「Ruby」。 –

回答

5
a 
.slice_before{|k, _| k} 
.map{|a| [a.first.first, a.map(&:last).join]} 
# => [[1, "abc"], [2, "ab"]] 

a 
.slice_before{|k, _| k} 
.map{|a| a = a.dup; [a.first.shift, a.join]} 
# => [[1, "abc"], [2, "ab"]] 
+0

'''在'a.map(&:last).join'後面錯過']'; –

+0

@LukasBaliak哎呀,謝謝。 – sawa

3
input = [[1, "a"], [nil, "b"], [nil, "c"], [2, "a"], [nil, "b"]] 
input.each_with_object({}) do |(k, v), acc| 
    acc[k] = "" if k 
    acc.values.last << v 
end.to_a 
#⇒ [[1, "abc"], [2, "ab"]] 
+0

'input.each_with_object({})''返回'{1 =>「abc」,2 =>「ab」}'錯過'.to_a';} –

+0

@LukasBaliak的確,謝謝,更新。 – mudasobwa

1
a.slice_before(&:first).map do |arr| 
    f, *rest = arr.flatten 
    [f, rest.join] 
end 
    #=> [[1, "abc"], [2, "ab"]] 

Enumerable#slice_beforeEnumerator#nextArray#join。關於join,使用NilClass#to_snil轉換爲字符串。

的步驟如下:

enum = a.slice_before(&:first) 
    #=> #<Enumerator: #<Enumerator::Generator:0x007fc6eb207858>:each> 

這相當於

enum = a.slice_before { |k,_| k } 

這枚舉將產生將被傳遞到塊兩個值:

enum.next 
    #=> [[1, "a"], [nil, "b"], [nil, "c"]] 

和然後

enum.next 
    #=> [[2, "a"], [nil, "b"]] 

enum.next 
    #=> StopIteration: iteration reached an end 

在繼續之前讓我枚舉數重置到年初Enumerator#rewind

enum.rewind 

被生成並被傳遞給塊的enum第一個值,由塊變量arr捕獲。

arr = enum.next 
    #=> [[1, "a"], [nil, "b"], [nil, "c"]] 

並且執行塊計算。

b = arr.flatten 
    #=> [1, "a", nil, "b", nil, "c"] 
f, *rest = b 
    #=> [1, "a", nil, "b", nil, "c"] 
f #=> 1 
rest 
    #=> ["a", nil, "b", nil, "c"] 
s = rest.join 
    #=> "abc" 
[f, s] 
    #=> [1, "abc"] 

enum第二值然後生成並傳遞到塊,並且執行所述塊的計算。

arr = enum.next 
    #=> [[2, "a"], [nil, "b"]] 
b = arr.flatten 
    #=> [2, "a", nil, "b"] 
f, *rest = b 
    #=> [2, "a", nil, "b"] 
f #=> 2 
rest 
    #=> ["a", nil, "b"] 
s = rest.join 
    #=> "ab" 
[f, s] 
    #=> [2, "ab"]