我有一个数组:
ak = [10, 20, 3, 4, 5, -5, 28, 27]
我想要一个这样的解决方案:
#even:4
#odd:3
#positive:7
#negative:1
我如何使用哈希来做到这一点?
答案 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