【问题标题】:Ruby: check if all array elements are equalRuby:检查所有数组元素是否相等
【发布时间】:2015-02-12 19:03:23
【问题描述】:

我在使用 Ruby 代码时遇到了一点“问题”。 我想检查一个数组的所有元素是否相等。

例如,假设我有一个只有 5s 的数组:

arr = [5, 5, 5, 5, 5]

我知道我可以做类似的事情

arr[0] == arr[1] == arr[2] == arr[3] # == arr[4] == ...

但这对于大型数组是不可能的,而且在我看来也不是很像 Ruby。 我们可以通过这样做来改进它:

def all_equal?(arr)
  for i in 0..(arr.size-2)
    if arr[i] != arr[i+1] then
      return false
    end
  end
  true
end

但我也认为这很丑陋。那么是否有任何内置/更好/更短(更像 Ruby 风格)的方式来做到这一点?

TL;DR 检查数组是否仅包含一个不同元素(例如 [5, 5, 5])的最短/最 Ruby 风格的方法是什么

谢谢。

【问题讨论】:

  • 如果arr 的元素都与<=> 相当,你可以这样做:arr.min==arr.max,但这显然是uniq 的工作。
  • arr[0] == arr[1] == arr[2] 真的吗?您使用的是哪个 Ruby 版本?

标签: ruby arrays equality


【解决方案1】:

您也可以使用.uniq,它返回一个没有重复的数组,并检查大小:

def all_equal?(arr)
    arr.uniq.size <= 1
end

【讨论】:

  • 恕我直言,它应该正好是 1。如果它更小,则取决于您的语义。空数组是否所有元素都相等? ;)
  • 确实可以解释——对我来说,一个空数组的所有元素都是相等的,因为它没有元素:) 而且它确实不是很有效,更好的方法是for。但在 ruby​​ 中,我们经常用速度来换取漂亮,因为这类操作在大多数应用程序中很少成为瓶颈。
【解决方案2】:

几种方法。

最好的:

array.uniq.count <= 1 # or == 1 if it can't be an empty array

还有:

array == ([array.first] * array.count)

还有:

(array | array).count <= 1 # basically doing the same thing as uniq

还有:

array.reduce(:|) == array.first # but not very safe

如果它是一个可排序的数组,那么:

array.min == array.max    

而且,只是为了多样化:

!array.any?{ |element| element != array[0] } # or array.first instead of array[0]

或者:

array.all?{ |element| element == array[0] } # or array.first instead of array[0]

【讨论】:

    【解决方案3】:

    使用Enumerable#each_cons:

    def all_equal?(xs)
      xs.each_cons(2).all? { |x, y| x == y }
    end
    

    【讨论】:

      【解决方案4】:

      对数组进行排序并将第一个值与最后一个值进行比较。

      【讨论】:

      • 我喜欢这个解决方案。它确实要求可以对数组进行排序/比较(并非总是如此),所以我将采用 Luan Nico 的回答。
      • 订购一个数组只是为了检查所有元素是否都是唯一的,效率不高。
      【解决方案5】:

      试试这个..

      array = ["cars","cars","truck", nil]
      array.uniq.compact.length == 1
      

      【讨论】:

        【解决方案6】:

        这适用于 Ruby 3.0+:

          [1,1,1,1].minmax.reduce(&:eql?)
        

        看起来很漂亮。不过可能不是最快的。

        【讨论】:

          猜你喜欢
          • 2019-07-04
          • 2018-05-13
          • 1970-01-01
          • 2012-12-16
          • 1970-01-01
          • 2019-05-25
          • 2023-04-06
          • 2013-01-27
          相关资源
          最近更新 更多