为什么我的回报搞砸了我的结果?

时间:2015-03-19 01:15:20

标签: ruby return-value

这段代码的目标(它是更大代码的一部分)是确定一年中是否有重复的数字。这是我的代码:

def no_repeat?(year)
  year = year.to_s
  string = ''

  year.each_char{|i| string << year[i] unless string.include?(year[i])}
  year.length == string.length ? (return false) : (return true)
  end 

puts no_repeat?(1993)

它总是返回true,我不明白为什么会这样。我已经尝试将三元扩展为完整的if语句...仍然返回true。我尝试将整个方法写成while循环(有两个索引将一个索引与另一个索引进行比较)

def no_repeat?(year)
  year = year.to_s

i = 0
while i < year.length 

    i2 = i + 1
    while i2 < year.length   

      if year[i] == year[i2]
        return false
      else
        return true
      end

      i2 += 1
    end
  i += 1
end

...仍然返回true。我已经独立测试了每一件事,他们一切正常,直到我把回报放进去。回报是什么?我需要新鲜的眼睛。

2 个答案:

答案 0 :(得分:2)

您构建三元组的方式不正确。由于您的方法试图确保不重复任何操作,因此当true为真时,它应返回==。三元本身旨在返回一个值,而不是真正在其结果中执行(return false)之类的表达式。 的作品,但实际上不存在是非常规的。

三元应该看起来像

return year.length == string.length ? true : false

当然可以简化,因为==表达式已经返回布尔值。

return year.length == string.length

接下来,您对year[i]的使用并不完全正确。 String#each_char正在将字符值分配到i,因此您可以直接使用i。看来你使用它的方式确实有效,但这不是迭代器变量i的用法。

这使您的方法成为:

def no_repeat?(year)
  year = year.to_s
  string = ''

  # i represents the character in this iteration
  # so you may just directly reference i here
  year.each_char{|i| string << i unless string.include?(i)}
  # If the lengths match, return true because there's no repeating character
  return year.length == string.length

  # You could omit the 'return' keyword too which is preferred by convention
  # since Ruby returns the last expression's value implicitly
  # year.length == string.length
end

答案 1 :(得分:2)

你翻了真假陈述。否则代码可以正常工作。

这有效:

def no_repeat?(year)
  year = year.to_s
  string = ''

  year.each_char{|i| string << year[i] unless string.include?(year[i])}
  year.length == string.length ? (return true) : (return false)
end

no_repeat?(1993) # => false
no_repeat?(2015) # => true

但是,有很多方法可以改进此代码。 Ruby中很少使用return关键字。事实上,在你的例子中它完全是多余的。这两种方法是等价的:

# with `return`
def no_repeat?(year)
  year = year.to_s
  string = ''

  year.each_char{|i| string << year[i] unless string.include?(year[i])}
  year.length == string.length ? (return true) : (return false)
end

# without `return`
def no_repeat?(year)
  year = year.to_s
  string = ''

  year.each_char{|i| string << year[i] unless string.include?(year[i])}
  year.length == string.length
end

其次,在方法名称中使用否定(&#34; no&#34;)会使代码难以理解。我建议翻转逻辑并调用方法repeat?或更好repeat_chars?

最后,有更简洁的方法来表达您使用内置Ruby方法编写的逻辑。这是一个替代实现(我确信其他Rubyists可以使用更优雅的解决方案):

def repeat_chars?(year)
  year = year.to_s
  year.length != year.chars.uniq.length
end