计算数组中的更改

我想计算一下这个数组中"red"后跟"green"

 ["red", "orange", "green", "red", "yellow", "blue", "green"] 

如果它是另一种颜色,代码应该忽略它并继续到数组中的下一个项目。

 event_type.each_slice(2) do |red, green| break unless green count = count + 1 end p "The count is #{count}" 

步骤1:

 Look for red 

第2步:

 IF not last item Compare with next item on array ELSE Go to Step 4 

第3步:

 IF green, count = count + 1 Go to Step 1 ELSE Go to Step 2 

第4步:

 Print Count 

以下是我认为的解决方案。 当然有更多的空间来重构它,你可以从这里开始。

 a = ["red", "orange", "green", "red", "yellow", "blue", "green"] a.reject {|e| !['red', 'green'].include? e } .each_cons(2) .select{|e| e == ['red', 'green']} .size 

更具艺术性的版本。

 def neither_red_nor_green e !['red', 'green'].include? e end def red_followed_by_green ary ary == ['red', 'green'] end a.reject(&method(:neither_red_nor_green)) .each_cons(2) .select(&method(:red_followed_by_green)) .size 

UPDATE

感谢@Stefan提出以下建议。

 def either_red_or_green e ['red', 'green'].include? e end def red_followed_by_green ary ary == ['red', 'green'] end a.select(&method(:either_red_or_green)) .each_cons(2) .count(&method(:red_followed_by_green)) 

UPDATE

正如Stefan Pochmann所提出的,

 a.select(&method(:either_red_or_green)) .each_cons(2) .count(['red', 'green']) 

将完成相同的工作,而无需另一个方法调用。

这是Ruby着名触发器的完美用例:

 input = %w[red orange green red yellow blue green] input.reduce(0) do |count, e| if (e == "red")..(e == "green") and (e == "green") count + 1 # inc on right boundary else count end end #⇒ 2 

还测试了

 %w[yellow green green red orange green red yellow blue green red yellow] 

FWIW,这是我回答的第二个问题,提出了一周内的触发器。 前一个在这里 。


Stefan Pochmann的清洁解决方案

 input.count { |x| x == "green" if (x == "red")..(x == "green") } 
 count, _ = ["red", "orange", "green", "red", "yellow", "blue", "green"] .inject([0, nil]) do |(count, state), word| if word == "red" state = :red elsif word == "green" and state == :red state = nil count += 1 end [count, state] end count # => 2 
 def count_red_to_green(arr) count = 0 unmatched_red = false arr.each do |colour| case colour when "red" unmatched_red = true when "green" if unmatched_red count += 1 unmatched_red = false end end end count end count_red_to_green ["red", "orange", "green", "red", "yellow", "blue", "green"] #=> 2