如何在Ruby中找到字符串的第一个非重复字母?

如何在Ruby中找到字符串的第一个非重复字母?,ruby,string,Ruby,String,我有一个字符串teststring。我想在Ruby中找到第一个非循环字符 我有以下Python代码: def first_non_repeat_character(teststring) unique=[] repeated=[] for character in teststring: if character in unique: unique.remove(character) repeated.app

我有一个字符串teststring。我想在Ruby中找到第一个非循环字符

我有以下Python代码:

def first_non_repeat_character(teststring)
    unique=[]
    repeated=[]
    for character in teststring:
        if character in unique:
            unique.remove(character)
            repeated.append(character)
        else:
            if not character in repeated:
                unique.append(character)
    if len(unique):
        return unique[0]
    else: 
        return false

这应该可以做到:

def first_non_repeat_character(teststring)
  group = teststring.chars.group_by {|i| i}.find {|letter, group| group.one? }
  group && group.first
end

由于ruby 2.2.1您可以使用group_by&:它本身

并向@broisasse点头表示基本想法,因此如果您使用ruby 2.2+的新方法,我建议他在irb或pry控制台中链接的答案有以下变化:

与定义方法相比,这种方法的优点在于可以很容易地回溯方法链以进行调试。如果没有得到预期的答案,只需不断删除方法链的尾部,直到找到问题。

另一个:

'teststring'.each_char.with_object(Hash.new(0)) { |c, h| h[c] += 1 }.key(1)
#=> "e"
一步一步地: 遍历每个字符:

'teststring'.each_char.to_a
#=> ["t", "e", "s", "t", "s", "t", "r", "i", "n", "g"]
将默认值为0的散列传递给块,以便对返回散列的每个字符进行计数:

'teststring'.each_char.with_object(Hash.new(0)) { |c, h| h[c] += 1 }
#=> {"t"=>3, "e"=>1, "s"=>2, "r"=>1, "i"=>1, "n"=>1, "g"=>1}
返回给定值的键,即字符,即计数为1

'teststring'.each_char.with_object(Hash.new(0)) { |c, h| h[c] += 1 }.key(1)
#=> "e"
可能的警告:尽管实现返回给定值的第一个键,但文档说明:

返回给定值的出现项的键

你可以写:

str = 'teststring'

arr = str.chars
(arr - (arr.difference(arr.uniq))).first
  #= "e"
在我的回答中定义了阵列差异

Arraydifference类似于Array-。以下示例说明了这种差异:

a = [1,2,3,4,3,2,2,4]
b = [2,3,4,4,4]

a     -      b #=> [1]
a.difference b #=> [1, 3, 2, 2]
因此,arr.differencearr.uniq返回arr.counte>1的所有元素e的数组

arr.differencearr.uniq返回重复出现的字符,因此

arr - arr.difference(arr.uniq)

返回非重复字符,按arr中的顺序排列。

以下是一个示例,其中考虑了是否有大写字母。例如,如果你通过

"sTresst" => "r"

def  first_non_repeating_letter(s) 
  s.each_char do |char|
    return char if s.downcase.count(char.downcase) < 2
  end
  ""
end

修正你的缩进,到现在为止,这是完全不可读的。这不是Ruby,这是Python的尝试。你说的第一个非重复字符是什么意思?到目前为止还没有找到的角色?或者是一个字符,后面不跟aa?我想找出一个到目前为止还没有找到的字符,我知道我是在python中找到的…..因为我是ruby新手,我不知道如何在rubyNo中做到这一点,这不起作用,对于“teststring”,答案应该是“e”,如果我传递的是“letter”,那么答案应该是“l”@vidal——这正是它为这些输入返回的结果。o_0您使用哪个ruby版本?@Stefan-所以他们最终发布了自己的方法?太棒了,我等了一会儿根据查找与选择-我不敢相信我错过了。00@Stefan唯一需要注意的是objectself在Ruby 2.2.0中是新的。只是未来的访问者应该知道的东西。@CodeGnome或来自过去的访问者-+1,因为我怀疑这是迄今为止性能最好的答案,因为它依赖于快速字符串方法,而不是链式哈希/数组方法。@CodeGnome取决于字符串的长度和非重复字符(如果有)的位置,由于嵌套计数,此方法多次遍历字符串。请注意,如果由于nil[0],字符串仅包含重复项,则第二种方法将引发错误。@Stefan Fixed。抢手货
arr - arr.difference(arr.uniq)
"sTresst" => "r"

def  first_non_repeating_letter(s) 
  s.each_char do |char|
    return char if s.downcase.count(char.downcase) < 2
  end
  ""
end