你需要知道的6个Ruby数组方法

时间:2022-06-01 12:52:29

数组是编程的基本结构之一,这里介绍6个Ruby操作数组的方法。

Map/Each

这两种方法非常相似。 它们让我们对数组的每一项执行操作。

示例:

array = [1, 2, 3]
effects = array.each{|x| # 根据x求值 }
added = array.map{ |x| x + 2 }

例子里:effects返回[1,2,3],added返回[2, 4, 5]。

map和each的区别:map将返回一个新的已修改数组,而each将返回原始数组。

Select

select用于查找数组元素。 select接收一个返回true或false的函数作为参数,用于标记元素是否符合查找条件。

示例:

2.3.0 :028 > array = ['hello', 'hi', 'goodbye']
2.3.0 :029 > array.select{|word| word.length > 3}
 => ["hello", "goodbye"]

在例子里加入map,让它稍微复杂一点:

2.3.0 :030 > valid_colors = ['red', 'green', 'blue']
2.3.0 :031 > cars = [{type: 'porsche', color: 'red'}, {type: 'mustang', color: 'orange'}, {type: 'prius', color: 'blue'}]
2.3.0 :032 > cars.select{ |car| valid_colors.include?(car[:color]) }.map{ |car| car[:type]}
=> ["porsche", "prius"]

.map(&:method)

.map(&:method)语法是一种更简洁的语法。

常规的map方法

2.3.0 :047 > cars.select{ |car| valid_colors.include?(car[:color]) }.map{|car| car.to_json}
 => ["{\"type\":\"porsche\",\"color\":\"red\"}", "{\"type\":\"prius\",\"color\":\"blue\"}"]

使用map(&:method)语法实现

2.3.0 :046 > cars.select{|car| valid_colors.include?(car[:color]) }.map(&:to_json)
 => ["{\"type\":\"porsche\",\"color\":\"red\"}", "{\"type\":\"prius\",\"color\":\"blue\"}"]

Reject

reject是与select相对应的。它返回拒绝的元素。

示例:

2.3.0 :048 > cars.reject{|car| valid_colors.include?(car[:color]) }.map{|car| car[:type]}
 => ["mustang"]

Reduce

Reduce相对其他的数组方法复杂一点,它主要用于数学方面,它对数组的每一项执行指定的函数,最后返回一个聚合的值。如对数组的每一项相加,计算其总数:

2.3.0 :049 > array = [1, 2, 3]
2.3.0 :050 > array.reduce{|sum, x| sum + x}
 => 6

合并字符串:

2.3.0 :053 > array = ['amber', 'scott', 'erica']
2.3.0 :054 > array.reduce{|sum, name| sum + name}
 => "amberscotterica"

Join

join用于把数组里的元素按字符串连接起来,并且可以指定元素之间的分割字符串。

示例:

2.3.0 :061 > cars.map{|car| car[:type]}.join(', ')
 => "porsche, mustang, prius"

组合操作

现在用一个例子把以上6个方法组合起来使用:

days = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
days.map{|day| day.odd? ? 
  {task: 'dishes', minutes: Random.rand(20)} :
  {task: 'sweep', minutes: Random.rand(20)}}
  .select{|task| task[:minutes] < 15}
  .reject{|task| task[:minutes] < 5}
  .reduce(0) {|sum, task| sum + task[:minutes]}