2014-10-05 103 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

相关问题