计算数组中的更改

时间:2018-02-21 06:32:45

标签: ruby counter

我想计算此数组中"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

4 个答案:

答案 0 :(得分:7)

对于Ruby着名的flip-flop来说,这是一个完美的用例:

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,这是我回答的第二个问题,暗示了一周内的触发器。之前的one is here

Stefan Pochmann的清洁解决方案

input.count { |x| x == "green" if (x == "red")..(x == "green") }

答案 1 :(得分:6)

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

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

<强>更新

感谢@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))

<强>更新

正如Stefan Pochmann所提议的那样,

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

将执行相同的工作,无需另外的方法调用。

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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