使用散列来区分正数、奇数、偶数和负数
Using hash to tell positive, odd, even, and negative numbers
我有一个数组:
ak = [10, 20, 3, 4, 5, -5, 28, 27]
我想要这样的解决方案:
#even:4
#odd:3
#positive:7
#negative:1
如何使用哈希来做到这一点?
您可以遍历数组并像这样测试每个值:
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
或者类似的东西。之后可以优化。
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
假设(基于您期望的输出)您只需要正偶数或奇数:
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
另一个解决方案:
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
您可以按如下所示以相当通用(可重用)的方式执行此操作。
代码
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, which calls Array#each 传递到块中。我们可以把enum
转成数组看看里面的元素是什么:
enum.to_a
#=> [[[:even, :even?], {}], [[:odd, :odd?], {}],
# [[:positive, #<Proc:0x007fe90395aaf8@(irb):9 (lambda)>], {}],
# [[:negative, #<Proc:0x007fe90395aaa8@(irb):10 (lambda)>], {}]]
并模拟将 enum
的 (4
) 个元素传递到带有 Enumerator#next 的块中。 enum
([[:even, :even?], {}]
)的第一个元素传递给块并赋值给块变量:
(k,m),h = enum.next
#=> [[:even, :even?], {}]
k #=> :even
m #=> :even?
h #=> {}
接下来,我们使用Hash#update(又名merge!
)将一键散列合并到h
和returnh
的新值中:
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))
写成 shorthand for ({k=>ak.count(&m)})
).
像往常一样,&
调用 Symbol#to_proc 将符号 :even?
转换为过程,然后将过程转换为 count
.[=45= 的块]
然后将enum
的下一个值传递给块("odd"),执行类似的计算并将散列{ :odd=>4 }
合并到h
中,结果在:
h #=> { :even=>4, :odd=>4 }
然后 enum
的第三个和第四个值被传递给块。唯一的区别是 ak.count(&m)
中的 m
已经是一个过程(实际上是一个 lambda),所以 &
只是将它转换为 count
.[=45= 的块]
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
我有一个数组:
ak = [10, 20, 3, 4, 5, -5, 28, 27]
我想要这样的解决方案:
#even:4
#odd:3
#positive:7
#negative:1
如何使用哈希来做到这一点?
您可以遍历数组并像这样测试每个值:
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
或者类似的东西。之后可以优化。
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
假设(基于您期望的输出)您只需要正偶数或奇数:
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
另一个解决方案:
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
您可以按如下所示以相当通用(可重用)的方式执行此操作。
代码
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, which calls Array#each 传递到块中。我们可以把enum
转成数组看看里面的元素是什么:
enum.to_a
#=> [[[:even, :even?], {}], [[:odd, :odd?], {}],
# [[:positive, #<Proc:0x007fe90395aaf8@(irb):9 (lambda)>], {}],
# [[:negative, #<Proc:0x007fe90395aaa8@(irb):10 (lambda)>], {}]]
并模拟将 enum
的 (4
) 个元素传递到带有 Enumerator#next 的块中。 enum
([[:even, :even?], {}]
)的第一个元素传递给块并赋值给块变量:
(k,m),h = enum.next
#=> [[:even, :even?], {}]
k #=> :even
m #=> :even?
h #=> {}
接下来,我们使用Hash#update(又名merge!
)将一键散列合并到h
和returnh
的新值中:
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))
写成 shorthand for ({k=>ak.count(&m)})
).
像往常一样,&
调用 Symbol#to_proc 将符号 :even?
转换为过程,然后将过程转换为 count
.[=45= 的块]
然后将enum
的下一个值传递给块("odd"),执行类似的计算并将散列{ :odd=>4 }
合并到h
中,结果在:
h #=> { :even=>4, :odd=>4 }
然后 enum
的第三个和第四个值被传递给块。唯一的区别是 ak.count(&m)
中的 m
已经是一个过程(实际上是一个 lambda),所以 &
只是将它转换为 count
.[=45= 的块]
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