如何在Ruby中正确使用inject方法

时间:2013-10-26 17:54:12

标签: ruby-on-rails ruby arrays ruby-on-rails-3

我仍然是一个红宝石新手,我正在努力学习如何使用inject方法。

通过使用inject方法,我试图在给定的字符串中返回一个字母数组及其外观,如下所示:

def sorting(str)
  str.split("").uniq.map { |letter|
    [letter, str.split("").inject(0) { |sum, char| sum + 1 if letter == char }]
  }
end

p sorting("aaabdbbcccaaabcacba")

欲望的结果应该是:

[["a", 8], ["b", 5], ["d", 1], ["c", 5]]

不幸的是,我收到了一个错误:undefined method '+' for nil:NilClass

我做错了什么,如何使用inject及其优势来解决?

2 个答案:

答案 0 :(得分:7)

使用Enumerable#group_by似乎更合适:

>> "aaabdbbcccaaabcacba".chars.group_by { |x| x }.map { |key, a| [key, a.size] }
=> [["a", 8], ["b", 5], ["d", 1], ["c", 5]]

给定代码的问题:

传递给inject的块不关心不匹配的字符。

sum + 1 if letter == char替换为letter == char ? sum + 1 : sum

def sorting(str)
    str.split("").uniq.map { |letter|
        [letter, str.split("").inject(0) { |sum, char| letter == char ? sum + 1 : sum }]
    }
end

答案 1 :(得分:1)

这是另一种方法:

s = "aaabdbbcccaaabcacba"
s.chars.uniq.map{|c|[c,s.count(c)]}
# => [["a", 8], ["b", 5], ["d", 1], ["c", 5]]