(Ruby)方法检查元素是否已经出现

时间:2017-05-06 16:33:29

标签: ruby

我正在尝试编写一种方法来检查我们是否在字符串中多次看到一个元素。这段代码返回的是字符串,但不是布尔值---而且我认为它甚至不会返回正确的字符串!

有人可以提供建议吗?

def repeating_letters?(str)
  # downcase the whole str
  # create a "seen letters" array
  # iterate through each char in array
  # if seen letters contains that character, return true
  down = str.downcase
  seen = []
  down.each_char do |index|
    if seen.include?(index)
      TRUE
    else
      seen << index
    end
  end
end

p repeating_letters?("aA")

5 个答案:

答案 0 :(得分:3)

你可以更轻松地做到这一点:

def repeated_characters?(s)
  !! s =~ /(.)\1/
end

没有数组,没有循环遍历字符串,没有计数,只是一个简单的正则表达式匹配任何字符后跟同一个字符。

或者,如果你不关心邻接,你可以这样做:

Set.new(s.chars).length == s.length

# or this:

s.each_char.uniq.length == s.length

答案 1 :(得分:2)

您的代码中存在的问题是,您不会浪费true小写,不使用它。你要做的事情并不是那么清楚。我原以为seen是哈希值。

def repeating_letters?(str)
  str.downcase.chars.group_by(&:itself).values.any? { |a| a.size > 1 }
end

itself可从Ruby 2.3.0获得,否则

def repeating_letters?(str)
  str.downcase.chars.group_by { |c| c }.values.any? { |a| a.size > 1 }
end

答案 2 :(得分:2)

您的代码不起作用,因为String#each_char返回接收者,即字符串。您必须使用明确的return :(我已经解决了一些小问题)

def repeating_letters?(str)
  seen = []
  str.downcase.each_char do |char|
    if seen.include?(char)
      return true           # <- you need a `return` here
    else
      seen << char
    end
  end
  return false              # <- last statement, so `return` is optional
end

或者你可以使用any?,如果该块返回true(否则返回true),则返回false

def repeating_letters?(str)
  seen = []
  str.downcase.each_char.any? do |char|
    if seen.include?(char)
      true
    else
      seen << char
      false
    end
  end
end

这可以通过使用散列来计算字符来缩短:

def repeating_letters?(str)
  seen = Hash.new(0)
  str.downcase.each_char.any? { |char| (seen[char] += 1) == 2 }
end

在块中,char的哈希值增加1并与2进行比较,后者表示之前是否看到过char。

我还会将downcase从方法移动到调用者,以使代码更加通用:

def repeating_letters?(str)
  seen = Hash.new(0)
  str.each_char.any? { |char| (seen[char] += 1) == 2 }
end

repeating_letters?('aA'.downcase)

答案 3 :(得分:0)

你可以这样做:

def check(str)
  repeated = false
  str.downcase.split.uniq.each { |i| repeated = true and break if str.count(i) > 1 }
  repeated
end

答案 4 :(得分:0)

def repeating?(str)
  str.downcase!
  seen = {}
  str.each_char.with_index do |char, index|
    if index !=0 && str[0..(index-1)].include?(char)
      seen[char] = seen[char].nil? ? 2 : seen[char]+=1
    end
  end
  seen
end

输出

> p repeating?("peEterr")
{"e"=>3, "a"=>2}