2014-10-05 118 views
4

我得到了錯誤,當我要加倍值添加到一個數組:Ruby的map方法在這種情況下如何工作?

arr = [1,2,3] 

def my_mistake(arr) 
    result = Array.new 
    arr.map { |element| result << element * 2 } 
end 
#=> [[2, 4, 6], [2, 4, 6], [2, 4, 6]] 

def solution(arr) 
    arr.map { |element| element * 2 } 
end 
#=> [2,4,6] 

然而,回來我的錯誤和紅寶石地圖方法的定義。

爲每個自我元素調用一次給定的塊。創建一個包含塊返回值的新數組。

我覺得my_mistake方法必須返回[[2], [2, 4], [2, 4, 6]]但事實並非如此。

大家可以爲我解釋這個案例嗎?

回答

5

生成的數組將包含三次出現的對同一個數組的相同引用,因爲result是表達式result << element * 2的結果。所以map的結果是(種)[result, result, result]。這些全部指向相同的內容,這是內容result在過程結束時([2, 4, 6])。

您所期望的,如果你在每個點克隆的陣列將可以實現,讓每一個產生元素將指向不同的數組,每個除了不會影響先前計算的陣列:

arr.map { |element| (result << element * 2).clone } 
=> [[2], [2, 4], [2, 4, 6]] 
+0

非常感謝,** Patrice **,因爲我的聲望我不能投票:(另外,你能給我鏈接或者你的信息來源嗎?:*結果數組將包含三個相同的引用結果* – 2014-10-05 14:29:49

+0

來自['Array#<<'](http://www.ruby-doc.org/core-2.1.3/Array.html#method-i-3C-3C)的@CuongVu:*「這個表達式返回數組本身,...「* – Stefan 2014-10-05 14:46:33

+0

@CuongVu那麼,正如Stefan指出的那樣,無論這個評估產生什麼樣的副作用,'result << element * 2'的每一個評估都會到達'result',而'result'是一個引用指向內存中的一個且只有一個數組當我說「...將包含三個對同一結果的引用」時,這確實是誤導性的:關於*三次出現的同一個引用*更準確* – 2014-10-05 15:12:11

0

.map返回最後評估的表達式,所以不需要結果< <那裏。這裏的東西爲我工作:

def my_mistake(arr) 
    result = [] # '= []' is same like '= Array.new', look-up "literal constructors in Ruby" 
    new_arr = [] # same like new_arr = Array.new 
    until arr.empty? 
    new_arr << arr.shift # we add each element of arr, one by one, starting from the beginning 
    output << new_arr.map { |e| e * 2} # we calculate *2 for each element 
    end 
    return result 
end 
p my_mistake(arr) #=> [[2], [2, 4], [2, 4, 6]] 

如果你n要知道如何工作的,可以嘗試在「P輸出」第6行後:

def my_mistake(arr) 
    output = [] 
    new_arr = [] 
    until arr.empty? 
    new_arr << arr.shift 
    output << new_arr.map { |e| e * 2} 
    p output 
    end 
    return output 
end 

my_mistake(arr) 

該程序將打印:

[[2]] 
[[2], [2, 4]] 
[[2], [2, 4], [2, 4, 6]] 
+0

感謝* * daremkd **,但我想知道'''map'''方法是如何工作的。我不想返回''[[2],[2,4],[2,4,6]]''。不過,我認爲你的解決方案適合這種情況:)。 – 2014-10-05 14:27:54

相關問題