Ruby:将字符串转换为二维数组

时间:2012-02-28 17:32:00

标签: ruby arrays

我需要转换一个字符串(检查板的64个字符表示):

game_state = "r_____r__r___r_rr_r___r__________________b_b______b_b____b_b___b"

到二维,8×8,检查器对象数组:

[ [red_checker, nil, nil, nil, nil....and so on times 8], ]

这是我做这件事的方式,这种做法很丑陋而且不是很像红宝石,就像接近结尾的增量一样。

def game_state_string_to_board(game_state)
    board = Board.new
    game_board = board.create_test_board

    game_state_array = []
    game_state.each_char { |char| game_state_array << char}
    row_index = 0
    game_state_array.each_slice(8) do |row|
      row.each_with_index do |square, col_index|
        unless square == '_'
          game_board[row_index][col_index] = create_checker(square, row_index, col_index)
        end
      end
      row_index += 1
    end
    game_board
  end

有没有人有更清洁,更简单,更红宝石的方式?感谢。

2 个答案:

答案 0 :(得分:2)

这样的事情应该有用(Ruby 1.9.x):

game_state = "r_____r__r___r_rr_r___r__________________b_b______b_b____b_b___b"

game_state.split( '' ).each_with_index.map do |square, idx|
  square == '_' ? nil : create_checker( square, idx / 8, idx % 8 )
end.each_slice( 8 ).to_a

输出:

[ [ #<RedChecker(0,0)>, nil, nil, nil, nil, nil, #<RedChecker(0,6)>, nil],
  [ nil, #<RedChecker(1,1)>, nil, nil, nil, #<RedChecker(1,5)>, nil, #<RedChecker(1,7)>],
  [ #<RedChecker(2,0)>, nil, #<RedChecker(2,2)>, nil, nil, nil, #<RedChecker(2,6)>, nil],
  [ nil, nil, nil, nil, nil, nil, nil, nil],
  [ nil, nil, nil, nil, nil, nil, nil, nil],
  [ nil, #<BlackChecker(5,1)>, nil, #<BlackChecker(5,3)>, nil, nil, nil, nil],
  [ nil, nil, #<BlackChecker(6,2)>, nil, #<BlackChecker(6,4)>, nil, nil, nil],
  [ nil, #<BlackChecker(7,1)>, nil, #<BlackChecker(7,3)>, nil, nil, nil, #<BlackChecker(7,7) ]
]

由于它有点密集,我会把它分解:

game_state.
  # change the string into an Array like [ "r", "_", "_", ...]
  split( '' ).

  # `each_with_index` gives us an Enumerable that passes the index of each element...
  each_with_index.

  # ...so we can access the index in `map`
  map do |square, idx|
    square == "_" ?
      # output nil if the input is "_"
      nil :
      # otherwise call create_checker
      create_checker( square,
        idx / 8,  # the row can be derived with integer division
        idx % 8   # and the column is the modulus (remainder)
      )
  end.

  # take the result of `map` and slice it up into arrays of 8 elements each
  each_slice( 8 ).to_a

答案 1 :(得分:1)

如果你想要一个8 x 8阵列,那就可以了:

game_state = "r_____r__r___r_rr_r___r__________________b_b______b_b____b_b___b"

game_state.split('').each_slice(8).to_a

"[[\"r\", \"_\", \"_\", \"_\", \"_\", \"_\", \"r\", \"_\"], [\"_\", \"r\", \"_\", \"_\", \"_\", \"r\", \"_\", \"r\"], [\"r\", \"_\", \"r\", \"_\", \"_\", \"_\", \"r\", \"_\"], [\"_\", \"_\", \"_\", \"_\", \"_\", \"_\", \"_\", \"_\"], [\"_\", \"_\", \"_\", \"_\", \"_\", \"_\", \"_\", \"_\"], [\"_\", \"b\", \"_\", \"b\", \"_\", \"_\", \"_\", \"_\"], [\"_\", \"_\", \"b\", \"_\", \"b\", \"_\", \"_\", \"_\"], [\"_\", \"b\", \"_\", \"b\", \"_\", \"_\", \"_\", \"b\"]]"

我不知道你的代码中的某些方法是做什么的,但这应该回答你的问题