用map替换数组元素

时间:2013-10-03 21:12:07

标签: ruby

我有两个数组:

@a = [ 
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]
@b = [a, b, c]

我需要将a中的第n列替换为b,如:

swap_column(0)
#=> [a, 2, 3]
    [b, 5, 6]
    [c, 8, 9]

(这是为了使用Cramer's rule解决方程式系统,如果有人想知道的话。)

我提出的代码:

  def swap_column(n)
    @a.map.with_index { |row, j| row[n] = @b[j] }
  end

如何在此处删除作业,以便map返回修改后的矩阵,同时保持@a完好无损?

3 个答案:

答案 0 :(得分:2)

你想要的是dup。此外,您有map.with_index块的返回值错误。

def swap_column(i)
  @a.map.with_index{|row, j| row = row.dup; row[i] = @b[j]; row}
end

def swap_column(i)
  @a.map.with_index{|row, j| row.dup.tap{|row| row[i] = @b[j]}}
end

答案 1 :(得分:1)

sawa的答案很好,重点是你需要dup你的内部数组才能正常工作。这篇补充帖子的唯一原因是要指出,通常当你使用with_index以便可以直接1:1索引到另一个数组时,你可以使用zip来简化代码。

def swap_column(n)
  @a.zip(@b).map {|r,e| r.dup.tap{|r| r[n] = e}}
end

zip的作用是将两个数组合并为一个新数组,其中每个元素都是由初始数组的两个相应元素组成的数组。在这种情况下,它将是一个数组的数组和您想要稍后用于替换的元素。然后,我们映射这些结果并自动将每个元素解构为两个部分。然后我们dup数组和tap替换第n个元素。

答案 2 :(得分:0)

您可以使用transpose执行以下操作:

class M
  attr :a, :b

  def initialize
    @a = [[1,2,3],
          [4,5,6],
          [7,8,9]
        ]
    @b = [:a, :b, :c]
  end

  def swap_column(n)
    t = @a.transpose
    t[0] = @b
    t.transpose
  end

end

m = M.new
=> #<M:0x007ffdc2952e38 @a=[[1, 2, 3], [4, 5, 6], [7, 8, 9]], @b=[:a, :b, :c]>
m.swap_column(0)
=> [[:a, 2, 3], [:b, 5, 6], [:c, 8, 9]]
m  # m is unchanged
=> #<M:0x007ffdc2952e38 @a=[[1, 2, 3], [4, 5, 6], [7, 8, 9]], @b=[:a, :b, :c]>