Ruby可枚举模块的详细介绍

153 阅读5分钟

可枚举模块介绍

模块是继承的主要结果,因为它们允许我们执行动作而不需要写代码,并在不相关的类之间共享功能。

由于Ruby是一种面向对象的编程语言,数据集合的作用非常重要。包含在枚举模块中的一些方法非常流行,人们往往认为它们是Ruby语言的组成部分。

这些模块中包含的方法可以根据其功能的性质进行分组。

  • 查询
  • 抓取
  • 搜索和过滤
  • 迭代
  • 其他

在这篇文章中,我们将回顾该模块的每一组,并分析其中的主要方法。但在此之前,我们需要回顾一些主题,这些主题对于理解数据集合的基础知识和如何与之交互是很关键的。

Enumerable vs Enumerator

把enumerable和enumerator的概念搞混是很常见的。因此,了解它们的区别以及它们之间的关系是很重要的。enumerable是一个封装了一组方法的模块,而enumerator是一个允许内部和外部迭代的类的定义。

换句话说,枚举器支持包含在可枚举模块中的所有方法。另外,枚举器的一个主要特点是,它们可以被连锁起来,并转化为新的枚举器。

根据Ruby的文档,要创建一个枚举器,我们可以使用to_enumEnumerator.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。firstlast 方法,正如其名称一样,返回该位置的元素。

user = ["Marta", 34, "Barcelona", 0]

user.first
#=> Marta

user.last
#=> 0

要使用takedrop ,我们需要指定我们想要获得/放弃的元素的数量。

user.take(2)
#=> ["Marta", 34]

user.drop(1)
#=> [34, "Barcelona", 0]

记住,这个逻辑是从第一个元素开始计算的,而不是从索引位置开始计算的!

通过使用take_whiledrop_while ,Take and drop也可以包括允许我们应用自定义标准的块。

使用最大值和最小值来获取元素也是一种常见的做法。这可以通过maxmin 方法来实现,或者两者的组合minmax ,它返回一个包含最小和最大值的数组。

另一种获取方法是使用group_by,partitionslice ,将元素分成组。它们之间的区别是,分组返回一个哈希值,其中包含根据给定条件分组的元素,在一个块中。而partition和slice方法返回两个或多个新数组。

注意,slice有不同的形式。slice_after,slice_beforeslice_when

搜索和过滤方法

搜索和过滤方法在验证数据集合的时候非常有用。另外,在构建用户界面时,它也有很多应用。通常,我们使用这些方法。

  1. find 或 。在一个块中给定detect一个条件,返回一个元素。如果有一个以上的元素,那么,符合条件的第一个元素将被返回。
numbers = [1, 2, 3, 4, 5]
numbers.find { |i| i > 1}
#=> 2
  1. filter 或 。在一个块中给定一个条件,返回一个元素select的集合
numbers = [1, 2, 3, 4, 5]
numbers.filter { |i| i > 1}
#=> [2, 3, 4, 5]

  1. uniq:返回一个或多个在数据集合中唯一的元素(如果有的话)。

排序方法

在访问或显示长的数据集合时,排序是很有用的。这方面的主要方法是sortsort_by 。一个快速的例子是。

array = ["a", "aaa", "aa"]
array.sort_by { |element| element.size }
#=> ["a", "aa", "aaa"]

迭代方法

对于迭代集合,除了each ,我们还可以使用模块中的一些变化,如reverse_eacheach_with_objecteach_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:重复循环浏览集合中的元素。

总结

枚举器是面向对象语言的关键,在这种语言中,有一种强大的方法来处理和与集合互动是至关重要的。使用枚举模块中的方法不仅是一种好的做法,而且比自己编写方法更可靠。