2017-01-28 66 views
1

以下函數設計用於接收數組數組並返回其子數組的最大值。Ruby:使用從子數組返回最大值數組的遞歸函數的問題

def temp(list) 
    if list.all? { |i| i.kind_of?(Array) } 
    return(list.each { |j| j.max }) 
    else 
    return(list) 
    end 
end 

所以給出的列表和函數調用是這樣的:

x = [[1, 2], [3, 4]] 

temp(x) 

它應該返回[2,4],而是它只是返回原始數組[1,2],[3 ,4]]。我想知道這裏發生了什麼問題。

感謝

+0

我們甚至可以進一步簡化爲'list.map {| each | [* each] .max}'如果它們處理混合數組很酷。我認爲他們可能是。 – akuhn

回答

0

你的列表中的每個成員上運行的代碼塊後回到列表本身。相反,您可以在該函數內創建另一個列表,並將該列表中的max值推回,並將其返回。

def temp(list) 
    if list.all? { |i| i.kind_of?(Array) } 
    maxlist=[] 
    list.each { |j| maxlist << j.max } 
    return maxlist 
    else 
    return(list) 
    end 
end 

x = [[1, 2], [3, 4]] 

puts temp(x) 

這將按預期輸出2和4。

+0

初始化一個空列表然後使用'each'附加到它是非常單一的。 'map'就是你應該在這裏使用的。 – meagar

+0

@meagar當然!我對Ruby還不是很有經驗,只是在閱讀了Jordan的回答之後才記起這種方法。不認爲在它之後編輯我的作品是公平的! – IanC

3

each對數組的每個元素進行操作,然後返回(原始)數組。你想用的方法map

def temp(list) 
    if list.all? {|i| i.kind_of?(Array) } 
    list.map {|j| j.max } 
    else 
    list 
    end 
end 

x = [[1, 2], [3, 4]] 
temp(x) 
# => [2, 4] 

但是,明確的類型檢查是不是習慣在Ruby中,它更喜歡鴨打字。不要檢查i是否爲Array;只是檢查它是否響應max

def temp(list) 
    return list unless list.all? {|i| i.respond_to?(:max) } 
    list.map(&:max) 
end 
+1

你也可以做'list.map {| l | l.send(l.respond_to?(:max)?:max::itself)}'允許在同一級別混合使用數組和標量。 –

+0

@MarkReed或'list.map {| l | l.respond_to?(:max)? l.max:l}'。 –

+1

你可以使用'list.map {| l | [* l] .max}'無論如何我們放鬆了所有的要求。 – akuhn

1

如果你放鬆了all?要求,然後...

試試這個

def temp(list) 
    list.map { |l| Array(l).max } 
end 

這是如何工作的?

  • Array(l)接通陣列成陣列
  • 並接通其它的目的爲單個元件陣列
  • 並接通nil到空數組
  • 因此我們可以隨時調用max
+1

你通常應該更喜歡'Array(l)',它實際上不會偷聽,而不是'[* 1]',這是一種將數組轉換爲自身的非常昂貴的方式,在功能上是沒有操作的。 – meagar

+0

良好的捕獲,更新。 – akuhn