Range在概念上看是非常直观的。不过在实际的使用中,我们可能会遇到一些令人混淆的东西。
看如下代码:
digits = 0..9 #0到9
scale1 = 0..10 #0到10
scale2 = 0...10 #0到9,不包含10
..操作符将包含上限,而...不包含上限。
不过,Range不只是作用于数字类型,基本上对于任何的对象都有用,但结果是否有实际意义要看实际的情况了。
a = 'A'..'Z'
a.to_a.each{|c| puts c}
我们称..这样的Range为"关闭"的Range,而...的Range为"开放"的Range。
使用first和last方法(或同义方法begin和end),可以获取一个Range的开始和结束元素:
r1 = 3..6
r2 = 3...6
r1a, r1b = r1.first, r1.last # 3, 6
r1c, r1d = r1.begin, r1.end # 3, 6
r2a, r2b = r2.begin, r2.end # 3, 6 (注意:不是3和5)
exclude_end?方法可以得到Range是否排除上限项(即是否是...的Range)
r1.exclude_end? # false
r2.exclude_end? # true
对Range进行迭代
========================================================
Range是可迭代的,不过,为了更加实际有用,确认你的Range包含的对象已经有一个有意义的succ方法。
(3..6).each {|x| puts x }
我们看一个有趣的例子:
r1 = "7".."9"
r2 = "7".."10"
r1.each {|x| puts x } # 打印出7,8,9
r2.each {|x| puts x } # 未打印任何东西
为什么会出现这样的情况?这是因为这里都是字符串,由于r1中,"7"比"9"小,所以,它是个合理的Range;而表达式r2中,
"7"比"10"大,下限大于了上限,就不合理了。
浮点数的Range可以进行迭代么?我们来看一下:
fr = 2.0..2.2
fr.each {|x| puts x } # 错误!
为什么浮点数不可以迭代呢?因为浮点数对象没有succ方法。是因为不能实现么?理论上,这是没有问题的,但是,实际上,如果浮点数
Range迭代,这有可能出现:很小的一个范围,将产生非常庞大的迭代量。这对语言的实现有非常高的要求。况且,这样的功能,极少有用到。
测试范围关系
===========================================================
include?方法(同义方法member?)可以判断一个值是否处在当前的Range中:
r1 = 23456..34567
x = 14142
y = 31416
r1.include?(x) # false
r1.include?(y) # true
它内部是怎么实现的呢?其实,它只是把给出的值和该Range的上限做比较得出的(所以,它依赖与一个有意义的<=>)。
转化为数组
============================================================
很简单,to_a方法搞定:
r = 3..12
arr = r.to_a # [3,4,5,6,7,8,9,10,11,12]
反向的Range
=============================================================
我们前面讨论过了下限大于上限的Range,如:
r = 6..3
x = r.begin # 6
y = r.end # 3
flag = r.end_excluded? # false
它确实是个合法的Range,但是,它包含的内容缺并不是我们想像的那样:
arr = r.to_a # 得到空的数组[]
r.each {|x| p x} # 无结果
r.include?(5) # false
那么说反向Range是没有什么用处的咯?那倒不是,我们可以在字符串和数组中使用反向Range:
string = "flowery"
str1 = string[0..-2] # "flower"
str2 = string[1..-2] # "lower"
str3 = string[-5..-3] # "owe" (其实这是个正向的Range)
分享到:
相关推荐
- Ruby有四种变量类型:局部变量(以小写字母或下划线开头),实例变量(以`@`开头),类变量(以`@@`开头)和全局变量(以`$`开头)。理解它们的作用域和用法是避免陷阱的关键。 - 常量在Ruby中是可变的,但改变...
在Ruby中操作Excel文件主要是通过`win32ole`库来实现的,这个库允许Ruby程序与Windows操作系统中的Office应用程序进行交互,如Microsoft Excel。以下是关于如何使用Ruby操作Excel的详细步骤和知识点: 1. **引入win...
Ruby的集合类型包括数组(Array)、哈希(Hash)、范围(Range)和集合(Set)。数组是有序的元素序列,哈希则是一组键值对,提供了基于键的访问。范围表示一个连续的数值序列,集合则不包含重复元素。 Ruby的标准...
9. **集合数据结构**:Ruby提供了多种内置的集合数据结构,如数组(Array)、哈希(Hash)、范围(Range)、集合(Set)等,每种都有其特定的用途和操作方式。 10. **错误处理**:Ruby使用`begin..rescue..end`来...
元类是类的类,即用来创建类的类,主要涉及到了Ruby的元编程特性。 **3.7 Ruby的动态性** Ruby的动态特性体现在其可以动态地创建类和方法,甚至可以在运行时修改现有的类和方法。 **3.8 变量** - **局部变量**:...
可以通过`Workbook`类的`Open`方法来打开一个已经存在的Excel工作簿。 ```ruby workbook = excel.Workbooks.Open('c:\examples\spreadsheet.xls') ``` #### 4. 选择工作表 在打开的工作簿中,可以通过`Worksheets`...
- 类与对象:Ruby中的万物皆对象,每个类都是Object类的子类。 - 继承与模块:Ruby支持单继承,但可以通过模块实现多重继承的效果,提供代码重用。 - 方法定义:包括实例方法、类方法、定义私有和保护方法等。 -...
`elasticsearch-ruby` 提供了丰富的查询API,例如 term 查询、match 查询、range 查询等。以下是一个基本的查询示例: ```ruby response = client.search index: 'products', body: { query: { match_all: {} } ...
Ruby是一种动态语言,允许在运行时修改类和对象。 **3.8 变量** - **局部变量**:作用域仅限于定义它们的方法或代码块。 - **实例变量**:以`@`开头,属于特定对象。 - **类变量**:以`@@`开头,属于类的所有实例...
- **动态性**:Ruby支持动态类型和运行时修改类结构。 - **脚本能力**:Ruby可以作为一种强大的脚本语言使用,适用于快速原型开发。 - **可扩展性**:通过C语言扩展,Ruby可以轻松地与其他语言集成。 ##### §1.4 ...
元类是定义类本身的类,在Ruby中,每个类都有一个元类,通过元类可以修改类的行为。 **3.7 Ruby的动态性** Ruby支持动态方法定义、方法重写等特性,使得程序能够在运行时动态地改变其行为。 **3.8 变量** - **...
Ruby有一些特殊的类和方法,如`Object`类是所有类的基类,`Kernel`类包含常用的基本函数。 **3.5 类变量与类方法** 类变量以`@@`开头,可在所有实例间共享;类方法则使用`self`关键字定义: ```ruby class ...
本中文教程旨在为初学者提供一个全面了解和学习Ruby的平台,包括基础语法、面向对象编程概念、控制结构、数据类型、方法、类与模块、错误与异常处理等核心内容。 1. **基础语法**:Ruby的基础语法简洁明了,易于...
ruby语法基础教程,比较全的。 目 录 Ruby语言 1 Grant Ren 1 第一部分 Ruby语言基础 8 第一章 Ruby语言概述 8 §1.1 Ruby的历史 8 §1.2 Ruby名字的由来 8 §1.3 Ruby的特点 8 §1.4 Ruby和Python的比较 9 第二章...
Ruby 支持多种类型的变量,包括局部变量、实例变量、类变量以及全局变量。 - 局部变量:以小写字母或下划线开头。 - 实例变量:以 `@` 符号开头。 - 类变量:以 `@@` 符号开头。 - 全局变量:以 `$` 符号开头。 ...