使用哈希来判断正数,奇数,偶数和负数

时间:2015-04-19 21:33:55

标签: ruby arrays hash

我有一个数组:

    ak = [10, 20, 3, 4, 5, -5, 28, 27]

我想要一个这样的解决方案:

    #even:4
    #odd:3
    #positive:7
    #negative:1

我如何使用哈希来做到这一点?

6 个答案:

答案 0 :(得分:4)

您可以按照以下相当普遍(可重复使用)的方式执行此操作。

<强>代码

def analyze_array(ak, ops)
  ops.each_with_object({}) { |(k,m),h| h.update(k=>ak.count(&m)) }
end

示例

ak = [10, 20, 3, 4, 5, -5, 28, 27]

ops = [[:even,     :even?       ],
       [:odd,      :odd?        ],
       [:positive, ->(n) { n>0 }],
       [:negative, ->(n) { n<0 }]]

analyze_array(ak, ops)
  #=> {:even=>4, :odd=>4, :positive=>7, :negative=>1} 

<强>解释

对于上面的示例:

enum = ops.each_with_object({})
  #=> #<Enumerator: [[:even, :even?], [:odd, :odd?],
  #    [:positive, #<Proc:0x007fe90395aaf8@(irb):9 (lambda)>],
  #    [:negative, #<Proc:0x007fe90395aaa8@(irb):10 (lambda)>]]
  #     :each_with_object({})> 

请注意,:even?:odd?是符号(不要与方法混淆)。

enum的元素通过Enumerator#each传递到块中,Array#each调用Enumerator#next。我们可以通过将enum转换为数组来查看enum.to_a #=> [[[:even, :even?], {}], [[:odd, :odd?], {}], # [[:positive, #<Proc:0x007fe90395aaf8@(irb):9 (lambda)>], {}], # [[:negative, #<Proc:0x007fe90395aaa8@(irb):10 (lambda)>], {}]] 的元素:

4

并模拟将enum的{​​{1}}元素传递到Hash#update的块中。 enum[[:even, :even?], {}])的第一个元素被传递给块并分配给块变量:

(k,m),h = enum.next
  #=> [[:even, :even?], {}] 
k #=> :even 
m #=> :even? 
h #=> {} 

接下来,我们使用Symbol#to_proc(又名merge!)将一键哈希合并到h并返回新值h

h.update(k=>ak.count(&m))
  #=> {}.update(:even=>[10, 20, 3, 4, 5, -5, 28, 27].count(&:even?))
  #=> {:even=>4}

(Ruby允许我们将(k=>ak.count(&m))写为({k=>ak.count(&m)}))的简写。

像往常一样,&调用{{3}}将符号:even?转换为proc,然后将proc转换为count的块。

然后将enum的下一个值传递给块(“奇数”),执行类似的计算并将哈希{ :odd=>4 }合并到h中,从而产生:

h #=> { :even=>4, :odd=>4 }

然后将enum的第三个和第四个值传递给块。唯一的区别是m中的ak.count(&m)已经是proc(实际上是lambda),因此&只是将其转换为count的块。

答案 1 :(得分:2)

   h = Hash.new
   h["even"] = ak.select {|x| x.even? && x > 0}.count
   h["odd"] = ak.select {|x| x.odd? && x > 0}.count
   h["positive"] = ak.select {|x| x > 0}.count
   h["negative"] = ak.select {|x| x < 0}.count

并添加

 put h

答案 2 :(得分:1)

另一种解决方案:

ak = [10, 20, 3, 4, 5, -5, 28, 27]
akp = ak.select{ |n| n > 0 }
h = {
  even: akp.count(&:even?),
  odd: akp.count(&:odd?),
  positive: akp.count,
  negative: ak.count{ |n| n < 0 }
}
puts ak, h

答案 3 :(得分:0)

您可以遍历数组并测试每个值,如下所示:

def evaluate(array)
  response = { even: 0, odd: 0, positive: 0, negative: 0 }
  array.each do |item|
    response[:even] += 1 if item.even?
    response[:odd] += 1 if item.odd?
    ...
  end
  response
end

或类似的东西。你可以在之后进行优化。

答案 4 :(得分:0)

def calculate(arr)
   even = arr.select {|e| e.even?}.size
   odd = arr.select {|e| e.odd?}.size
   pos = arr.select {|e| e >= 0}.size
   neg = arr.select {|e| e < 0}.size

   hash = {even: even, odd: odd, positive: pos, negative:neg}
end

答案 5 :(得分:0)

假设(基于您期望的输出)您只需要正偶数或奇数:

h = Hash.new
h["even"] = ak.select {|x| x.even? && x > 0}.count
h["odd"] = ak.select {|x| x.odd? && x > 0}.count
h["positive"] = ak.select {|x| x > 0}.count
h["negative"] = ak.select {|x| x < 0}.count

puts h