我使用的是Ruby 2.4。我有一个字符串数组,都是数字。我想计算数组中唯一的元素数量,它们也比它们之前的元素大(我认为第一个数组元素已经大于它不存在的前任元素)。所以我试过
data_col = ["3", "6", "10"]
#=> ["3", "6", "10"]
data_col.map { |string| string.to_i.to_s == string ? string.to_i : -2 }.each_cons(2).select { |a, b| a > b && data_col.count(a) == 1 }.count
#=> 0
但结果是零,尽管我的数组中的所有元素都满足我的标准。我怎样才能改进这种方式呢?
答案 0 :(得分:3)
require 'set'
def nbr_uniq_and_bigger(arr)
processed = Set.new
arr.each_cons(2).with_object(Set.new) do |(n,m),keepers|
if processed.add?(m)
keepers << m if m > n
else
keepers.delete(m)
end
end.size + (processed.include?(arr.first) ? 0 : 1)
end
nbr_uniq_and_bigger [1, 2, 6, 3, 2]
#=> 2
nbr_uniq_and_bigger [1, 2, 1, 2, 1, 2]
#=> 0
请参阅Set.add?。
注意可以写出keepers.delete(m)
行
keepers.delete(m) if keepers.key(m)
但是尝试删除不在集合中的元素不会造成伤害。
答案 1 :(得分:1)
这里有一些问题:
a > b
似乎与您要测试的内容相反。那应该是b > a
。data_col.count(a)
总是为零,因为a
是一个整数而data_col
只包含字符串。此外,我不确定您是否希望寻找a
... b
可能是寻找合适的元素。这里有一些有用的代码:
def foo(x)
([nil] + x).each_cons(2).select { |a, b| (a == nil or b > a) and x.count(b) == 1 }.count()
end
p foo([3, 6, 10]) # 3
p foo([3, 6, 10, 1, 6]) # 2
(如果您有一个字符串数组,请先.map { |s| s.to_i }
开始。)
答案 2 :(得分:1)
还有一个解决方案:
def uniq_and_bigger(data)
counts = data.each_with_object(Hash.new(0)) { |e, h| h[e] += 1 } #precalculate
data.each_cons(2).with_object([]) do |(n,m), a|
a << m if m > n && counts[m] == 1
end.size + (counts[data[0]] == 1 ? 1 : 0)
end
uniq_and_bigger([3, 6, 10, 1, 6])
=> 2
uniq_and_bigger([1, 2, 1, 2, 1, 2])
=> 0
答案 3 :(得分:0)
另一个解决方案。它是O(n)
,它会返回[3, 6, 10]
所需的结果。
它使用slice_when
:
def unique_and_increasing(array)
duplicates = array.group_by(&:itself).select{ |_, v| v.size > 1 }.keys
(array.slice_when{ |a, b| a < b }.map(&:first) - duplicates).size
end
p unique_and_increasing [3, 6, 10]
# 3
p unique_and_increasing [3, 6, 10, 1, 6]
# 2
p unique_and_increasing [1, 2, 1, 2, 1, 2]
# 0