## 6.数组
阵列可以视为机架。 你可以将任何东西 1 放在机架中,以类似的方式可以将任何东西放在阵列中。 一个机架包含许多架子或隔层。 如果你可以数数,则可以在每个隔间上放置数字,可以认为机架是用于存储某些东西的空间阵列。 每个隔间可以用数字标识,因此易于识别。 阵列是可供程序员使用的机架。 让我们看一个示例以了解更多信息。 在下面输入程序并执行
```rb
# array.rb
my_array = []
my_array << "Something"
my_array << 123
my_array << Time.now
my_array.each do |element|
puts element
end
```
这就是你将获得输出的方式
```rb
Something
123
Tue Feb 02 18:10:06 +0530 2010
```
让我们遍历程序,以`my_array = []`行,在其中声明一个名为`my_array`的数组,它是一个没有任何内容的空数组。 `[]`表示一个空数组,我们将其分配给`my_array`。 这样做后,我们在以下语句中填充一些值
```rb
my_array << "Something"
my_array << 123
my_array << Time.now
```
我们将元素追加到数组。 在第一条语句中,我们附加字符串常量`“Something”`,在第二条语句中,我们附加整数`123`,在第三条语句中,我们附加当前时间。 如果你猜对了,我们已经使用`<<`运算符将值附加到数组。
到现在为止,我们已经创建了一个名为`my_array`的数组,并将其放入其中。 现在,我们必须查看所输入的内容。为此,我们使用`<array_name>.each`(每个数组名称点一个点)。 此方法提取数组的每个元素。 因此,对于 my_array,我们使用`my_array.each`
好了,我们必须对数组的每个元素做一些事情。 为此,我们添加了`do … end`,我们可以在其中进行某些操作,因此我们的代码将转换为
```rb
my_array.each do
end
```
我们必须将数组的每个元素捕获到一个变量中,让我们使用名为`element`的变量来完成这项工作,因此我们使用以下代码捕获每个元素
```rb
my_array.each do |element|
end
```
注意我们如何将`element`变量放在`|`和`|`之间。 我们已经捕获了数组的每个元素,现在该怎么办? 我们将使用`puts`语句打印它。 这样我们的数组就可以成功打印了。 以下程序也与以前的程序相同,但是我们使用`Array.new`而不是`[]`来表示`my_array`是一个数组 <sup class="footnote">[ [23](#_footnotedef_23 "View footnote.") ]</sup>
```rb
# array_1.rb
my_array = Array.new
my_array << "Something"
my_array << 123
my_array << Time.now
my_array.each do |element|
puts element
end
```
我将编写另一个程序,该程序将使用`for`构造遍历数组的每个元素,如下所示
```rb
# array_2.rb
my_array = Array.new
my_array << "Something"
my_array << 123
my_array << Time.now
for element in my_array
puts element
end
```
输出量
```rb
Something
123
2012-08-10 19:19:47 +0530
```
还有第三种创建数组的方法。 请仔细查看下面的程序。 看`my_array = [ "Something", 123, Time.now ]`。 仔细看,我们有`my_array`那是一个我们要为其分配数组的变量,其设置为`[ "Something", 123, Time.now ]`。 也就是说,在这种情况下,我们在同一条语句中声明并向`my_array`添加了数组元素或值。 请注意,我们将数组的元素放在方括号中,这是声明和填充数组的另一种方法。 因此,程序 [array_3.rb](code/array_3.rb) 的工作原理与 [array_1.rb](code/array_1.rb) 和 [array.rb](code/array.rb) 完全相同,但更加简洁。 与许多语言不同,Ruby 让程序员选择自己的编码风格。
```rb
# array_3.rb
my_array = [ "Something", 123, Time.now ]
puts my_array.join("\n")
```
Output
```rb
Something
123
Wed Feb 03 17:37:36 +0530 2010
```
直到最后一个示例,我们使用每个示例来循环访问数组元素,现在我们将使用一种新的循环,即`for`循环,因此这里是一个代码
```rb
# array_for.rb
my_array = Array.new
my_array.push("Something")
my_array.push 123
my_array << Time.now
for element in my_array
puts element
end
```
Output
```rb
Something
123
2014-11-12 10:37:22 +0530
```
请参阅上面我们采用的新构造,这是:
```rb
for element in my_array
puts element
end
```
注意这一行`for element in my_array`。 这等效于`my_array.each |element` | 在前面的示例中。 `for`循环我个人觉得有点优雅。 因此,就像`each`一样,`my_array`中的每个元素都被加载到`element`中,这在循环块中可供程序员使用。 在这里,我们只使用`puts element`打印它。
### 6.1。 有关阵列的更多信息
现在让我们看一些数组函数。 为此,我们将使用我们最喜欢的 irb 而不是文本编辑器
```rb
>> array = Array.new
=> []
```
好的,在上面的语句中,我们看到我们使用`Array.new`创建了一个名为`array`的数组。 `Array.new`创建一个空数组。 还有另一种创建数组的方法。 我们可以通过直接指定数组中包含的值来创建它,如下所示
```rb
>> array = ["Something", 123, Time.now]
=> ["Something", 123, Tue Feb 02 20:30:41 +0530 2010]
```
在上面的语句中,我们创建了一个包含三个对象的数组。 必须在数组中的值在方括号`[`和`]`之间给出。 数组中的每个对象都用逗号分隔。 通过不提供`[`和`]`之间的值,我们甚至可以创建一个空数组,如下所示
```rb
>> array = []
=> []
```
在上面的示例中,空白`[]`与 Array.new 的工作相同。
让我们使用`Array.new`中的参数创建数组,如下所示
```rb
>> array = Array.new("Something", 123, Time.now)
ArgumentError: wrong number of arguments (3 for 2)
from (irb):3:in `initialize'
from (irb):3:in `new'
from (irb):3
from :0
```
如你所见,它失败了! 不要那样使用。
好的,现在让我们在`array`上进行一些尝试,首先要获取`array`中有多少个元素,我们可以使用`length`函数,如下所示:
```rb
>> array.length
=> 3
```
`join`函数将许多数组元素连接在一起并返回它。 因此,当将数组中的元素连接在一起时,这就是结果:
```rb
>> array.join(', ')
=> "Something, 123, Tue Feb 02 20:30:41 +0530 2010"
```
请注意,当数组元素作为字符串连接时,我们将字符串`', '`传递给`join`。 我们传递的字符串将插入它们之间。
我们已经创建了一个数组,并且其中包含一些东西,如果我们想添加一些东西,该怎么办? 为此,我们使用`push`方法。 在下面的示例中,我们将数字 5 推入`array`,然后看到数组得到扩展,最后将 5 附加到`array`。
```rb
>> array.push(5)
=> ["Something", 123, Tue Feb 02 20:30:41 +0530 2010, 5]
```
`pop`方法的作用与`push`相反,它弹出或删除数组的最后一个元素。 参见下面的示例,我们弹出一个元素,然后弹出最后一个元素 5。
```rb
>> array.pop
=> 5
```
弹出后,让我们看看`array`中的内容
```rb
>> array
=> ["Something", 123, Tue Feb 02 20:30:41 +0530 2010]
```
我们看到数组大小减少了一个,最后一个元素 5 丢失了。
它不是只需要在`push`中给出固定值,而是可以将变量和 Ruby 表达式以及任何对象作为参数提供给 push。 你可以在下面看到我们将 2 提升到 10 的幂到数组,最后将 1024 添加到数组。
```rb
>> array.push 2**10
=> ["Something", 123, Tue Feb 02 20:30:41 +0530 2010, 1024]
```
索引数组元素。 数组的第一个元素的索引号为 0,并且继续(理论上一直到无穷大)。 如果要访问索引中的元素,则他要做的就是将索引号放在方括号之间。 在下面的示例中,我们访问名为`array`的数组的第三个元素,因此我们将其键入如下
```rb
>> array[2]
=> Tue Feb 02 20:30:41 +0530 2010
```
`pop`方法接受一个 Integer 作为参数,用于弹出`n`数组的最后一个元素。
```rb
>> array.pop(2)
=> [Tue Feb 02 20:30:41 +0530 2010, 1024]
>> array
=> ["Something", 123]
```
如你所见,第三个元素被弹出,因此可以随机弹出。
我们可以一次将许多元素推入数组。 考虑下面的代码片段
```rb
>> array.push 5, "Who am I?", 23.465*24
=> ["Something", 123, 5, "Who am I?", 563.16]
```
我们首先将 3 个新元素推入数组,然后得到一个更大的元素。
现在我们弹出最后 3 个元素
```rb
>> array.pop 3
=> [5, "Who am I?", 563.16]
```
如你所见,数组的大小减小了,现在只有两个元素。
```rb
>> array
=> ["Something", 123]
```
还有另一种在数组中追加元素的方法,它使用小于运算符`<<`的 double,使一些元素随其推入数组,如下所示:
```rb
>> array << "a new element"
=> ["Something", 123, "a new element"]
>> array << 64
=> ["Something", 123, "a new element", 64]
```
如你在上面看到的,我们使用`<<`运算符将字符串常量`“a new element”`和`64`附加到数组。
你可以使用`max`和`min`函数在数组中找到最大值和最小值,如下所示:
```rb
>> nums = [1, 2, 64, -17, 5 ,81]
=> [1, 2, 64, -17, 5, 81]
>> nums.max
=> 81
>> nums.min
=> -17
```
如上例所示,我们创建了一个名为`nums`的数组,其中包含一些数字,`nums.max`返回该数组中的最大值,`nums.min`返回该数组中的最小值。
### 6.2。 数组挖掘
看一下在 irb 中执行的一个简单代码段,我们有一个嵌套数组,可以说我们要访问字符串元素`“Treasure”`,可以使用 dig 方法,如下所示
```rb
>> array = [1, 5, [7, 9, 11, ["Treasure"], "Sigma"]]
=> [1, 5, [7, 9, 11, ["Treasure"], "Sigma"]]
>> array.dig(2, 3, 0)
=> "Treasure"
```
### 6.3。 设定操作
对于那些了解集合论的人,你必须了解交集,并集。 我在学校时读过关于集合论的文章,但现在已经忘记了。 你可以将数组视为集合并对其执行许多操作。 以下是一些我在 irb 上试过的例子,让我们参加一个大学排球队,其中有些人叫 Ashok,Chavan,Karthik,Jesus 和 Budha。 如果你列出板球队的名单,那就有 Budha,Karthik,Ragu 和 Ram。 现在让我们用 ruby 对其进行编码。 为了收集排球队成员,我们创建了一个数组,如下所示
```rb
>> volleyball=["Ashok", "Chavan", "Karthik", "Jesus", "Budha"]
=> ["Ashok", "Chavan", "Karthik", "Jesus", "Budha"]
```
以类似的方式,我们创建了另一个数组,其中包含板球队中球员的姓名,如下所示
```rb
>> cricket=["Budha", "Karthik", "Ragu", "Ram"]
=> ["Budha", "Karthik", "Ragu", "Ram"]
```
因此,我们有两组人。 现在要找出谁在排球和板球运动中,我们所需要做的就是使用&运算符对两个数组进行 AND(或取交)
```rb
>> volleyball & cricket
=> ["Karthik", "Budha"]
```
从上面的代码片段中可以看到,`&`(和)运算符会嗅出两个数组中都存在的那些元素。 在数学中,这种东西称为交集。
让我们说在另一种情况下,我们想找出所有排球和板球队的人。 为此,我们使用 or 运算符`|`。 现在应用它
```rb
>> volleyball | cricket
=> ["Ashok", "Chavan", "Karthik", "Jesus", "Budha", "Ragu", "Ram"]
```
如你所见,我们获得了排球队和板球队成员的名字。 | (或)运算符不同于+(加号)运算符。 让我们增加排球队和板球队
```rb
>> volleyball + cricket
=> ["Ashok", "Chavan", "Karthik", "Jesus", "Budha", "Budha", "Karthik", "Ragu", "Ram"]
```
从上面的代码片段中可以看到,名称 Karthik 和 Budha 是重复的。 当我们使用|时,这不会发生。 (OR)运算符。
现在让我们找出哪些球员只为排球队效力。 为此,我们将使用`–`(减号)运算符减去排球队的板球运动员,如下所示
```rb
>> volleyball - cricket
=> ["Ashok", "Chavan", "Jesus"]
```
因此,我们看到排球队中只有三名球员。 因此,如果你是数学家,你会对 Ruby 感到满意。
### 6.4。 空数组为真
Ruby 开发人员还必须了解其他内容。 它关于条件和空数组。 启动你的 irb 并输入
```rb
>> puts "A" if []
A
=> nil
```
如果你看到的话,即使传递给`if`语句的数组为空,该语句也会打印 A。 这有点违背了最不令人惊讶的理论,但是请不要感到惊讶。 有一个书架,里面有书,所以如果你这样说
```rb
>> puts "Books Present" if ["treasure island", "I Love Ruby"]
Books Present
=> nil
```
它确实按预期方式打印 Books Present。 但是在这件事上
```rb
>> puts "Books Present" if []
Books Present
=> nil
```
它仍然会打印有书本。 那是因为即使书架是空的,也有一个仍然是物体的书架。 因此,有些事情不是`nil`。 因此,它是`true`。 为确保其工作原理,请看下面的代码
```rb
>> nil.class
=> NilClass
>> [].class
=> Array
```
当我们查询什么是`nil`的类时,它表示其`NilClass`实际上是一个空东西。 但是,当我们查询空数组的类时,它仍然是`Array`,而不是`nil`或`false`,因此不是`true`。 检查必须执行的空数组
```rb
>> puts "A" unless [].empty?
=> nil
>> puts "A" if [].first
=> nil
```
在第一个中,`[].empty?`返回`true`,但是由于它在`unles`中,因此将无法执行依赖于它的语句。
如果看到第二个我们使用`[].first`,则返回`nil`。 在 irb 中尝试
```rb
>> [].first
=> nil
```
因此,这也可以用于检查数组是否为空。 还是这样.....?
```rb
>> a= [ nil, 1, 2, nil]
=> [nil, 1, 2, nil]
>> puts "a is empty" unless a.first
=> a is empty
>> puts "a is not empty" if a.first
=> nil
>> puts "a is not empty" unless a.empty?
a is not empty
=> nil
```
不用考虑天气还是不使用`first`检查空度?
### 6.5。 压缩阵列
有时一个数组可能包含`nil`值,而你想删除它,在这种情况下,你可以在该数组上调用`compact`。 让我们尝试一个例子。 启动你的 irb 或 pry,然后输入以下内容
首先让我们初始化数组
```rb
>> a = [1, nil, 2, nil, 3, nil]
=> [1, nil, 2, nil, 3, nil]
```
因此,在上面的语句中,我们使用三个`nil`值初始化了数组。 现在,如下所示通过压缩将`nil`值删除
```rb
>> a.compact
=> [1, 2, 3]
```
凉! 因此,红宝石删除了`nil`值,例如魔术。 现在让我们看看`a`的样子
```rb
>> a
=> [1, nil, 2, nil, 3, nil]
```
令我们沮丧的是,仍然保留了零值,真正发生了什么? 好吧,当你在`a`上调用 compact 时,将创建一个新的压缩数组,并将其返回给我们的 REPL <sup class="footnote">[ [24](#_footnotedef_24 "View footnote.") ]</sup> ,然后 REPL 将其打印出来。 那么如何使`a`真正改变呢? 如下所示,带有 bang 或`compact!`的简单调用紧凑型;)
```rb
>> a.compact!
=> [1, 2, 3]
>> a
=> [1, 2, 3]
```
### 6.6。 转换数组值
Ruby 带有非常强大的数组操作,我们将看到如何在易于使用的命令中转换数组。
#### 6.6.1。 收藏
火起来你的撬或 irb 并输入以下内容
```rb
>> array = [1, 2, 3]
=> [1, 2, 3]
>> array.collect{ |element| element * element }
=> [1, 4, 9]
```
在上面的代码中,我们声明了类型为`Array`的变量`array`,在下一条语句中,我们在其上调用了名为`collect`的方法,并传递了此代码块`{ |element| element * element }`。 现在让我们看看它的作用。
调用`collect`时,首先创建一个返回数组。 在该块中,我们看到了一个名为`|element|`的东西,现在 collect 算法的工作原理如下。 首先,此数组具有值 1、2 和 3,因此此块运行 3 次。 在第一次运行期间,将 1 装入`element`,现在在块中我们指定了`element * element`,因此`1 * 1`为`1`,并将其压入返回数组。 现在返回数组为`[1]`。
现在,它取第二个值,即 2,并且发生相同的过程,现在返回数组为`[1, 4]`,类似地,返回数组最终变为`[1, 4, 9]`并返回。
`collect`不会修改调用它的对象,因此,如果你查看`array`是什么,它仍将与下面的显示相同
```rb
>> array
=> [1, 2, 3]
```
你可以在 irb 中检查它。 如果要收集以修改被调用的对象,请使用爆炸符号,如下所示
```rb
>> array.collect!{ |element| element * element }
=> [1, 4, 9]
>> array
=> [1, 4, 9]
```
#### 6.6.2。 keep_if
假设我们要在数组中具有匹配特定条件的元素,并想删除其他条件,我们可以使用`keep_if`函数,如下所示
```rb
>> array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> array.keep_if{ |element| element % 2 == 0}
=> [2, 4, 6, 8, 10]
```
我们上面有一个由十个元素组成的数组,并说我们要保持偶数或被 2 整除的元素,因此我们将其写为如下所示的语句
```rb
array.keep_if{ |element| element % 2 == 0}
```
我们向`keep_if`传递了一个块。 其中,数组中的每个值都在`|element|`中捕获,并写入了条件`element % 2 == 0`,如果条件为 true,则该元素将保留在数组中,否则将其抛出。 `keep_if`修改了其调用的数组,与之不同的是,collect 返回新数组。 因此,如果在运行`keep_if`之后检查数组,其内容将发生更改。
#### 6.6.3。 delete_if
与`keep_if`相对,`delete_if`的作用恰好相反,下面显示了如果在 Array 对象上运行`delete_if`会发生什么。
```rb
>> array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> array.delete_if{ |element| element % 2 == 0}
=> [1, 3, 5, 7, 9]
>> array
=> [1, 3, 5, 7, 9]
```
### 6.7。 阅读红宝石文档
毫无疑问,这本书不够全面,无法涵盖所有Ruby Array 库。 要了解更多信息,请在此处阅读 Ruby 文档 [https://ruby-doc.org/core-2.5.1/Array.html](https://ruby-doc.org/core-2.5.1/Array.html)
- 前言
- 红宝石
- 先决条件
- 1.安装 Ruby
- 2.在线资源
- 3.入门
- 4.比较与逻辑
- 5.循环
- 6.数组
- 7.哈希和符号
- 8.范围
- 9.功能
- 10.可变范围
- 11.类&对象
- 12.安全导航
- 13.打破大型程序
- 14.结构和 OpenStruct
- 15. Rdoc
- 16. Ruby 样式指南
- 17.模块和混入
- 18.日期和时间
- 19.文件
- 20. Proc,Lambda 和块
- 21.多线程
- 22.异常处理
- 23.正则表达式
- 24.宝石
- 25.元编程
- 26.基准
- 27.测试驱动开发
- 28.观察者模式
- 29.模板模式
- 30.工厂模式
- 31.装饰图案
- 32.适配器模式
- 33.单例模式
- 34.复合模式
- 35.建造者模式
- 36.策略模式
- 赞助商
- 捐
- 人们怎么说
- 版权
- 取得这本书