可枚举模块介绍
模块是继承的主要结果,因为它们允许我们执行动作而不需要写代码,并在不相关的类之间共享功能。
由于Ruby是一种面向对象的编程语言,数据集合的作用非常重要。包含在枚举模块中的一些方法非常流行,人们往往认为它们是Ruby语言的组成部分。
这些模块中包含的方法可以根据其功能的性质进行分组。
- 查询
- 抓取
- 搜索和过滤
- 迭代
- 其他
在这篇文章中,我们将回顾该模块的每一组,并分析其中的主要方法。但在此之前,我们需要回顾一些主题,这些主题对于理解数据集合的基础知识和如何与之交互是很关键的。
Enumerable vs Enumerator
把enumerable和enumerator的概念搞混是很常见的。因此,了解它们的区别以及它们之间的关系是很重要的。enumerable是一个封装了一组方法的模块,而enumerator是一个允许内部和外部迭代的类的定义。
换句话说,枚举器支持包含在可枚举模块中的所有方法。另外,枚举器的一个主要特点是,它们可以被连锁起来,并转化为新的枚举器。
根据Ruby的文档,要创建一个枚举器,我们可以使用to_enum 或Enumerator.new 。
外部迭代与内部迭代
也许,你已经听说过不同类型的迭代,并试图理解它的复杂性,这并不小!但是,我们将保持它的复杂性。然而,在这篇文章中,我们将保持简单,并坚持在实际方面。
Ruby中的数据集合(枚举器)允许外部和内部迭代。当迭代一个项目集合中的元素时,我们所做的是对列表中的每个元素进行操作。在内部迭代中,该操作将在每个元素上执行,即使它是一个无限的列表。而外部迭代则需要通过明确调用每个元素来循环整个集合。
如何实现enumerable模块
实现和使用enumerable模块是非常容易的,特别是它已经包含在Ruby的主要类(array,hash, range, dir)、宝石(即devise)和项目(Ruby on Rails)中。
然而,如果你必须在一个类中手动包含该模块,你可以按照Ruby文档的指南include Enumerable 。
可列举的方法
用于查询的方法
查询方法是用来获取枚举器的信息的。最常见的是。
-
包括?返回一个布尔值。真,如果数据集合包括一个特定的对象
-
所有?、任何?、没有?、一个?返回一个布尔值。真,如果数据集合的所有元素都符合特定的标准,一些,没有或正好有一个。
-
count。返回一个整数,表示在一个集合内满足一个标准的次数。
answers = ("yes", "yes", "no")
answers.count("yes")
#=> 2
- tally:返回一个新的Hash,其中包含满足块中指定标准的元素。
抓取方法
让我们从简单的获取方法开始:first, last, take 和 drop。first 和last 方法,正如其名称一样,返回该位置的元素。
user = ["Marta", 34, "Barcelona", 0]
user.first
#=> Marta
user.last
#=> 0
要使用take 和drop ,我们需要指定我们想要获得/放弃的元素的数量。
user.take(2)
#=> ["Marta", 34]
user.drop(1)
#=> [34, "Barcelona", 0]
记住,这个逻辑是从第一个元素开始计算的,而不是从索引位置开始计算的!
通过使用take_while 和drop_while ,Take and drop也可以包括允许我们应用自定义标准的块。
使用最大值和最小值来获取元素也是一种常见的做法。这可以通过max 和min 方法来实现,或者两者的组合minmax ,它返回一个包含最小和最大值的数组。
另一种获取方法是使用group_by,partition 和slice ,将元素分成组。它们之间的区别是,分组返回一个哈希值,其中包含根据给定条件分组的元素,在一个块中。而partition和slice方法返回两个或多个新数组。
注意,slice有不同的形式。slice_after,slice_before 和slice_when 。
搜索和过滤方法
搜索和过滤方法在验证数据集合的时候非常有用。另外,在构建用户界面时,它也有很多应用。通常,我们使用这些方法。
find或 。在一个块中给定detect一个条件,返回一个元素。如果有一个以上的元素,那么,符合条件的第一个元素将被返回。
numbers = [1, 2, 3, 4, 5]
numbers.find { |i| i > 1}
#=> 2
filter或 。在一个块中给定一个条件,返回一个元素select的集合。
numbers = [1, 2, 3, 4, 5]
numbers.filter { |i| i > 1}
#=> [2, 3, 4, 5]
uniq:返回一个或多个在数据集合中唯一的元素(如果有的话)。
排序方法
在访问或显示长的数据集合时,排序是很有用的。这方面的主要方法是sort 和sort_by 。一个快速的例子是。
array = ["a", "aaa", "aa"]
array.sort_by { |element| element.size }
#=> ["a", "aa", "aaa"]
迭代方法
对于迭代集合,除了each ,我们还可以使用模块中的一些变化,如reverse_each 、each_with_object 或each_with_index 。让我们看一下最后一个变体,以了解其逻辑。
list = ["eat", "sleep", "work", "play"]
list.each_with_index { |element, index| p "#{index + 1}. #{element}" }
#=> 1. eat
#=> 2. sleep
#=> 3. work
#=> 4. play
记住,索引是从0开始的,这就是为什么我们在这个例子中要加1,以获得一个合适的列表。
其他方法
最后但并非最不重要的是,我们在这个模块中还有一些不同性质的方法,值得分析一下。
map:返回一个新版本的对象,对每个元素进行了特定的操作(在块上指定)。
(1..3).map { |e| e+1 }
#=> [2, 3, 4]
-
map_with_index:一个值得一看的map方法的替代方法! -
filter_map:与map方法类似,但返回一个元素的集合,这些元素在给定的过滤条件下验证为真。 -
sum:返回构成数据集合的元素的总和。
(1..3).sum
#=> 6
(1..3).sum { |e| e+1 }
#=> 9
cycle:重复循环浏览集合中的元素。
总结
枚举器是面向对象语言的关键,在这种语言中,有一种强大的方法来处理和与集合互动是至关重要的。使用枚举模块中的方法不仅是一种好的做法,而且比自己编写方法更可靠。