【问题标题】:Ruby: Hash assignment with concurrent loopsRuby:具有并发循环的哈希分配
【发布时间】:2012-01-11 22:26:58
【问题描述】:

假设我有一个数组:

array = [6, 6, 6, 4, 4, 6, 4, 4]

我还有另一个字符串数组:

quadrant = ["upper_left", "upper_right", "lower_left", "lower_right"]

我有一个 8 x 8 二维数组,由 nil 或 Checker 对象组成的棋盘位置 (@board)。

我的目标是创建一个这样的哈希:

hash = { "upper_left" => @board[array[0]][array[1]] ,
         "upper_right" => @board[array[2]][array[3]] ,
         "lower_left" => @board[array[4]][array[5]] ,
         "lower_left" => @board[array[6]][array[7]] }

我有以下代码:

jump_positions = {}
QUADRANTS.each do |quad|
        array.each_slice(2) do |coord|
          jump_positions[quad] = @board[coord[0]][coord[1]]
        end

然后是测试:

it "should assign board locations as adjacent positions and deliver that info as a whole" do
    @bs.board = board.create_board
    x_coord = 3
    y_coord = 1
    jump_assignments = @bs.assign_adjacent_positions(x_coord, y_coord)
    jump_assignments["upper_left"].class.should == nil
    jump_assignments["upper_right"].class.should == nil
    jump_assignments["lower_left"].class.should == Checker
    jump_assignments["lower_right"].class.should == Checker 
end

失败,因为所有分配都属于“Checker”类,结果它们都是同一个“Checker”对象。我知道这样做是因为循环是嵌套的,所以所有的“四”键都被初始化到最后一个板位置。

有没有一种方法可以一次性将值分配给具有“数组”中的值的键,以便正确分配它们?这个问题还有意义吗?

【问题讨论】:

  • 可以发一下assign_adjacent_positions的方法吗?
  • 这个结局和this question差不多吗?只需稍作修改即可将 2 元素数组用作 @board 中的索引。
  • @mu is too short 它类似,但有一些关键区别:我不只是用字符串压缩数组值,我必须将这些值包含为 board 属性的索引(这是一个二维数组),最终结果是一个包含在板二维数组中的对象,由 array.each_slice 方法传递的坐标表示 抱歉,如果这有点令人费解,非常感谢您的回复。
  • @mu 太短了所以我意识到我的算法设计很糟糕:没有必要让哈希包含实际的板对象,坐标就足够了,在这种情况下,你可以使用相当棒的 zip 方法在另一个问题中向我解释的效果很好。感谢您让我重新考虑我的问题,这可能比回答它更好。希望惠斯勒的赛季早日开始!
  • 我调整了我的其他答案以提取 @board 位置。我在你评论的时候设置它,所以我们互相错过了。我不介意你删除这个问题,没什么大不了的。

标签: ruby arrays hash iteration parallel-assignment


【解决方案1】:

亩太短让我重新考虑我的问题,我相信我的算法被打破了。实际上,我最终将此方法分解为三个相互依赖的方法:

def deltas_to_board_locations(deltas, x, y)
    board_coords = []
    deltas.each_slice(2) do |slice|
      board_coords << x + slice[0] 
      board_coords << y + slice[1]
    end
    board_coords
  end    

  def assign_adjacent_board_coords(x, y) 
    jump_positions = Hash[QUADRANTS.zip(deltas_to_board_locations(normal_deltas, x, y).each_slice(2))]    
  end

  def determine_adjacent_positions_content(board, board_coords)
    adjacent_content = {}
    board_coords.each_pair { |quad, coords| adjacent_content[quad] = board[coords[0]][coords[1]] }
    adjacent_content
  end  

效果很好。

【讨论】:

    【解决方案2】:

    我认为您只需在我对您的other similar question 的回答中添加一点map

    hash = Hash[quadrant.zip(array.each_slice(2).map { |a| @board[a.first][a.last] })]
    

    给定这样的板:

    @board = [
        ['11', '12', ... '18'],
        ['21', '22', ... '28'],
        ...
        ['81', '82', ... '88']
    ]
    

    上面的构造给了我一个hash,像这样:

    {
        "upper_left"  => "77",
        "upper_right" => "75",
        "lower_left"  => "57",
        "lower_right" => "55"
    }
    

    这似乎就是你要找的东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-07
      • 2019-10-29
      • 1970-01-01
      • 2012-03-05
      相关资源
      最近更新 更多