ruby一维数组转二维数组
The following article is part of a series. For more articles in this series, see Cloning the Game 2048 in Ruby. For the complete and final code, see the gist.
以下文章是系列文章的一部分。 有关本系列中的更多文章,请参阅在Ruby中克隆2048游戏。 有关完整和最终的代码,请参见要点。
Now that we know how the algorithm will work, it's time to think about the data this algorithm will work on. There are two main choices here: a flat array of some kind, or a two-dimensional array. Each has their advantages, but before we make a decision, we need to take something into account.
现在我们知道了该算法将如何工作,现在该考虑该算法将要处理的数据了。 这里有两个主要选择:某种平面阵列或二维阵列。 每个都有其优势,但是在做出决定之前,我们需要考虑一些因素。
干拼图 ( DRY Puzzles )
A common technique in working with grid-based puzzles where you have to look for patterns like this is to write one version of the algorithm that works on the puzzle from left to right and then rotate the entire puzzle around four times. This way, the algorithm only has to be written once and it only has to work from left to right. This dramatically reduces the complexity and size of the hardest part of this project.
处理基于网格的拼图时,您必须寻找这样的模式的一种常见技术是编写一种算法版本,该算法从左到右对拼图进行处理,然后将整个拼图旋转四次。 这样,算法仅需编写一次,并且仅需从左到右工作。 这大大降低了该项目最难部分的复杂性和规模 。
Since we'll be working on the puzzle from left to right, it makes sense to have the rows represented by arrays. When making a two dimensional array in Ruby (or, more accurately, how you want it to be addressed and what the data actually means), you have to decide whether you want a stack of rows (where each row of the grid is represented by an array) or a stack of columns (where each column is an array). Since we're working with rows, we'll choose rows.
由于我们将从左到右处理难题,因此使行由数组表示是有意义的。 在Ruby中制作二维数组时(或更准确地说,是如何寻址它以及数据的实际含义),您必须决定是否要堆叠一排(网格的每一行都由数组)或一列列(其中每一列都是一个数组)。 由于我们正在处理行,因此我们将选择行。
How this 2D array is rotated, we'll get to after we actually construct such an array.
实际构造此类2D数组之后,我们将介绍如何旋转2D数组。
构造二维数组 ( Constructing Two Dimensional Arrays )
The Array.new method can take an argument defining the size of the array that you want. For example, Array.new(5) will create an array of 5 nil objects. The second argument gives you a default value, so Array.new(5, 0) will give you the array [0,0,0,0,0]. So how do you create a two dimensional array?
Array.new方法可以使用一个参数,该参数定义所需的数组大小。 例如, Array.new(5)将创建一个由5个nil对象组成的数组。 第二个参数为您提供默认值,因此Array.new(5,0)将为您提供数组[0,0,0,0,0] 。 那么如何创建一个二维数组?
The wrong way, and the way I see people trying often is to say Array.new( 4, Array.new(4, 0) ). In other words, an array of 4 rows, each row being an array of 4 zeroes. And this appears to work at first. However, run the following code:
错误的方式,以及我看到人们经常尝试的方式,是说Array.new(4,Array.new(4,0)) 。 换句话说,是4行的数组,每行是4个零的数组。 首先,这似乎起作用。 但是,运行以下代码:
It looks simple. Make a 4x4 array of zeroes, set the top-left element to 1. But print it and we get…
看起来很简单。 制作一个4x4的零数组,将左上角的元素设置为1。但是打印出来,我们得到…
It set the entire first column to 1, what gives? When we made the arrays, the inner-most call to Array.new gets called first, making a single row. A single reference to this row is then duplicated 4 times to fill the outer-most array. Each row is then referencing the same array. Change one, change them all.
它将整个第一列设置为1,这有什么用? 当我们制作数组时,对Array.new的最里面的调用首先被调用,从而形成一行。 然后,将对此行的单个引用重复4次以填充最外面的数组。 然后,每一行都引用相同的数组。 换一个,全部改变。
Instead, we need to use the third way of creating an array in Ruby. Instead of passing a value to the Array.new method, we pass a block. The block is executed every time the Array.new method needs a new value. So if you were to say Array.new(5) { gets.chomp }, Ruby will stop and ask for input 5 times. So all we need to do is just create a new array inside this block. So we end up with Array.new(4) { Array.new(4,0) }. Now let's try that test case again.
相反,我们需要使用在Ruby中创建数组的第三种方法。 我们没有传递值到Array.new方法,而是传递了一个块。 每当Array.new方法需要一个新值时,就执行该块。 因此,如果您要说Array.new(5){gets.chomp} ,Ruby将停止并要求输入5次。 因此,我们要做的就是在此块中创建一个新数组。 因此,我们最终得到Array.new(4){Array.new(4,0)} 。 现在,让我们再次尝试该测试用例。
And it does just as you'd expect.
它确实如您所愿。
So even though Ruby doesn't have support for two-dimensional arrays, we can still do what we need. Just remember that the top-level array holds references to the sub-arrays, and each sub-array should refer to a different array of values.
因此,即使Ruby不支持二维数组,我们仍然可以执行所需的操作。 请记住,顶级数组包含对子数组的引用 ,并且每个子数组都应引用不同的值数组。
What this array represents is up to you. In our case, this array is laid out as rows. The first index is the row we're indexing, from top to bottom. To index the top row of the puzzle, we use a[0], to index the next row down we use a[1]. To index a specific tile in the second row, we use a[1][n]. However, if we had decided on columns… it would be the same thing. Ruby doesn't have any idea what we're doing with this data, and since it doesn't technically support two-dimensional arrays, what we're doing here is a hack. Access it only by convention and everything will hold together. Forget what the data underneath is supposed to be doing and everything can fall apart real fast.
该数组表示的内容取决于您。 在我们的例子中,此数组布置为行。 第一个索引是我们要索引的行,从上到下。 要为难题的第一行建立索引,我们使用a [0] ,为下一个索引,我们使用a [1] 。 为了索引第二行中的特定图块,我们使用a [1] [n] 。 但是,如果我们决定在列上……那将是同一回事。 Ruby并不知道我们要如何处理这些数据,并且由于它在技术上不支持二维数组,因此我们在这里要做的事情是黑客。 仅按约定访问它,所有内容将结合在一起。 忘记下面的数据应该做什么,一切都会很快崩溃。
翻译自: https://www.thoughtco.com/two-dimensional-arrays-in-ruby-2907737
ruby一维数组转二维数组