意外的关键字 - 否则

时间:2017-08-21 13:38:18

标签: ruby

我有一个方法返回找出哪个给定数字在均匀度上与其他数字不同并返回它的索引(+1)。

def iq_test(numbers)
  new_array = numbers.split(" ").collect {|n| n.to_i}
  x = new_array.select(&:even?)
    y = new_array.select(&:odd?)

  if x.count > y.count
    new_array.split.each_with_index do |value, index| 
      "#{index + 1}".to_i if value % 3 != 0
  else  y.count > x.count
      "#{index + 1}".to_i if value % 2 == 0
    end
  end
end

例如iq_test("2 4 7 8 10")应该返回3

但是,我正在接收

  

语法错误,意外的keyword_else,期待keyword_end

我无法找到关闭某些代码的地方。

3 个答案:

答案 0 :(得分:5)

这将是部分代码审查和答案。让我们从第一部分开始:

  new_array = numbers.split(" ").collect {|n| n.to_i}
  x = new_array.select(&:even?)
    y = new_array.select(&:odd?)
  • 花时间考虑好的变量名称。我不会使用“new_array”作为变量名,因为它没有提供任何关于它包含什么的线索。做这种事太多次了,程序变得难以理解。
  • xy真的是evensodds,不是吗?那些变量名称会更好。
  • 常见的Ruby习语是为数组使用复数名称,为其他所有名称使用单数名称。
  • 默认情况下,split会在空白处拆分,因此(" ")是不必要的。
  • 小心缩进。
  • 您的选择很好,但有一个快捷方式:可枚举的partition
  • 这实际上是我自己的风格,但在处理数组中的所有值时使用map,而只在执行从对象数组中提取属性时使用collect。 (换句话说,我经常使用map。)
  • 请注意,(&:to_i){|n| n.to_i}
  • 的一种捷径

考虑到上述情况,改写后,这部分可能如下所示:

numbers = input.split.map(&:to_i)
evens, odds = numbers.partition(&:even?)

现在让我们看看其余部分:

if x.count > y.count
    new_array.split.each_with_index do |value, index| 
      "#{index + 1}".to_i if value % 3 != 0
  else  y.count > x.count
      "#{index + 1}".to_i if value % 2 == 0
    end
  end

让我们考虑一下您收到的错误消息:意外关键字else;预期end。这包含了回答问题所需要知道的所有内容(如果您考虑这些问题,您会发现大多数错误消息都会发生)。它说它找到了一个else,它预计会end。这正是问题所在,您需要在end之前放置else来关闭do / end块。此外,您的else部分缺少迭代逻辑。

其他说明:

  • 再次注意缩进。你的end不符合他们的结局。正确的对齐可以帮助捕获这些类型的错误。使用像Rubymine这样的IDE或者支持Ruby的复杂文本编辑器也可以提供帮助。
  • else条款是独立的,您不会在它们之后添加条件。也许你的意思是elsif正如霍尔格评论的那样。
  • 使用字符串插值("#{}")将表达式转换为字符串。在这里,您将index + 1转换为字符串,然后返回到.to_i的整数,将其取消,可以这么说。只需index + 1即可。
  • Array#index可用于确定值的索引。
  • 目前尚不清楚是否需要所有索引以防万一。

以下是考虑上述情况的版本:

if evens.count > odds.count
  odds.map{|n| numbers.index(n) + 1}
elsif odds.count > evens.count
  evens.map{|n| numbers.index(n) + 1}
end

如果你喜欢这种事,请将你的工作代码带到http://codereview.stackexchange.com/

答案 1 :(得分:1)

此特定错误是因为您的Help -> Eclipse Marketplace...阻止没有结束end。要修复此错误,您需要:

each_with_index

答案 2 :(得分:0)

<强>代码

def odd_one_out(str)
  evens, odds = str.split.partition { |s| s.to_i.even? }
  case [evens.size <=> 1, odds.size <=> 1]
  when [0, 1] then evens.first
  when [1, 0] then odds.first
  else nil
  end
end

<强>实施例

odd_one_out "0 3 4 6"  #=> "3"
odd_one_out "1 5 7 8"  #=> "8"
odd_one_out "0 2 4 6"  #=> nil
odd_one_out "1 5 7 9"  #=> nil
odd_one_out "0 2 3 5"  #=> nil
odd_one_out "3"        #=> nil
odd_one_out "8"        #=> nil
odd_one_out ""         #=> nil

<强>解释

请参阅Integer#<=>

假设

str = "0 3 4 6"

然后

a = str.split
  #=> ["0", "3", "4", "6"]
evens, odds = a.partition { |s| s.to_i.even? }
  #=> [["0", "4", "6"], ["3"]]
evens
  #=> ["0", "4", "6"]
odds
  #=> ["3"]
b = [evens.size <=> 1, odds.size <=> 1]
  #=> [1, 0]
b == [0, 1]
  #=> false
b == [1, 0]
  #=> true
c = odds.first
  #=> "3"

case语句以及方法返回"3"