Arrays Ruby如何确定数组是否只有唯一的条目?

Arrays Ruby如何确定数组是否只有唯一的条目?,arrays,ruby,Arrays,Ruby,我想知道数组是否只包含唯一的(不同的)条目 我不想操纵原始数组,所以 uniq!{|项目|……}→ 一元还是零 ... 如果未进行任何更改(即未找到重复项),则返回nil 似乎不是正确的解决方案。否则我可能会做[1,2,3,4].uniq!。无? 与复杂但性能更好的解决方案相比,我更喜欢优雅、可读的解决方案。如果数组较大,您可能希望使用一种方法,按顺序检查元素并在找到dup时停止,而不是遍历整个数组。您可以使用散列高效地执行此操作: array.uniq.size == array.size a

我想知道
数组
是否只包含唯一的(不同的)条目

我不想操纵原始数组,所以

uniq!{|项目|……}→ 一元还是零 ... 如果未进行任何更改(即未找到重复项),则返回nil

似乎不是正确的解决方案。否则我可能会做
[1,2,3,4].uniq!。无?


与复杂但性能更好的解决方案相比,我更喜欢优雅、可读的解决方案。

如果数组较大,您可能希望使用一种方法,按顺序检查元素并在找到dup时停止,而不是遍历整个数组。您可以使用散列高效地执行此操作:

array.uniq.size == array.size
array.to_set.size == array.size
array.all? { |element| array.count(element) == 1 }
def dups?(arr)
  arr.each_with_object({}) do |e,h|
    return true if h[e]
    h[e] = true
  end
  false
end

dups? [1,2,3,1,4,5,6,3,1,8,9]
  #=> true
dups? [1,2,3,4,5,6,-6,-5,-4,-3,-2,-1]
  #=> false
…或与一组:

require 'set'

def dups?(arr)
  arr.each_with_object(Set.new) do |e,s|
    return true if s.include? e
    s << e
  end
  false
end
require'set'
def dups?(arr)
带对象(Set.new)的每个|
如果s.include返回true?E

我知道我说过“比起复杂但性能更好的解决方案,我更喜欢优雅、可读的解决方案。”但您的第一个示例虽然可读,但似乎至少复制了uniq版本作为新数组。看起来效率很低。不是吗?@berkes,效率应该更低-是的。非常低效-取决于您的用例。您正在比较大小。这比简单地比较阵列更有效吗?换句话说:
array.uniq.size==array.size
array.uniq==array
@berkes有什么好处,
=
如果数组中确实包含重复的元素,则会短路。但是,如果没有,则第一个数组中的每个元素都将与第二个数组中的每个元素进行比较,即使您知道如果大小相同,则数组是相同的(在本例中)。这是一个很好的观点,如果你不在乎的话,省略
size
会使它更加简洁。@berkes,渐进地说,前两个是
O(n)
时间和空间,最后一个是
O(n^2)
时间(可能更好地使用摊销分析)和
O(1)
空间。最佳选择是
O(n)
time,
O(1)
space。第一个非常可爱!
def dups?(arr)
  arr.each_with_object({}) do |e,h|
    return true if h[e]
    h[e] = true
  end
  false
end

dups? [1,2,3,1,4,5,6,3,1,8,9]
  #=> true
dups? [1,2,3,4,5,6,-6,-5,-4,-3,-2,-1]
  #=> false
require 'set'

def dups?(arr)
  arr.each_with_object(Set.new) do |e,s|
    return true if s.include? e
    s << e
  end
  false
end