你需要知道的6个Ruby数组方法
数组是编程的基本结构之一,这里介绍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]}