【问题标题】:Determining whether one array contains the contents of another array in ruby确定一个数组是否包含ruby中另一个数组的内容
【发布时间】:2010-05-18 07:17:53
【问题描述】:

在 ruby​​ 中,我如何测试一个数组不仅包含另一个数组的元素,而且按特定顺序包含它们?

correct_combination = [1, 2, 3, 4, 5]
[1, 5, 8, 2, 3, 4, 5].function_name(correct_combination) # => false
[8, 10, 1, 2, 3, 4, 5, 9].function_name(correct_combination) # => true

我尝试使用include,但这是用来测试[1,2,3].include?(2)是否为真。

【问题讨论】:

  • @jassa 我尝试使用它(没有 should,这是 rspec 的东西),[8, 10, 1, 2, 3, 4, 5, 9] =~ correct_combinationcorrect_combination =~ [8, 10, 1, 2, 3, 4, 5, 9] 都返回了 nil 用于 ruby​​ 2.0.0dev (2011-11- 27 后备箱 33860)。
  • 你说得对,让我详细说明

标签: ruby arrays


【解决方案1】:

你可以使用 each_cons 方法:

arr = [1, 2, 3, 4, 5]
[1, 5, 8, 2, 3, 4, 5].each_cons(arr.size).include? arr

在这种情况下,它适用于任何元素。

【讨论】:

  • 我认为 each_cons 仅在 Ruby 1.9 中可用?但一个不错的解决方案。
【解决方案2】:

我觉得很简单。

class Array
  def contain? other; (self & other) == other end
end

correct_combination = [1, 2, 3, 4, 5]
[1, 5, 8, 2, 3, 4, 5].contain?(correct_combination) # => false
[8, 10, 1, 2, 3, 4, 5, 9].contain?(correct_combination) # => true

【讨论】:

  • 我认为这对于检查数字是否按给定顺序出现并不准确。例如,如果 correct_combination = [1,3,4][1, 5, 8, 2, 3, 4, 5].contain?(correct_combination) 返回 true。
  • 这是预期的结果。你可能没有理解这个问题。
【解决方案3】:

如果你想忽略顺序,(就像我遇到这篇文章时所做的那样),你可以使用 Array.sort 和 http://ruby-doc.org/core-1.8.7/classes/Array.html#M000316

a = [1, 2, 3, 4, 5]
b = [2, 1, 5, 4, 3]
a.sort <=> b.sort

然后您需要检查输出值是否等于 0。

【讨论】:

  • 如果一个数组的内容比另一个数组多,这会起作用吗?
  • 不,因为 正在测试相等性,并且我们已经做到了,如果每个数组中的值相同,那么它们在排序后将相等。正如链接文档所说:因此,根据 Array# 两个数组“相等”当且仅当它们具有相同的长度并且每个元素的值等于另一个中对应元素的值数组。
【解决方案4】:

不是最好的解决方案,但至少是简短的

(',' + [1, 5, 8, 2, 3, 4, 5].join(',') + ',').include?(',' + correct_combination.join(',') + ',')

可能的最佳解决方案是在数组上使用string searching algorithms 之一,但您必须自己编写代码,我认为没有标准解决方案。

【讨论】:

    【解决方案5】:

    这是我想出来的

    a = [1, 2, 3, 4, 5]
    b = [2, 3, 5]
    c = [3, 9]
    
    irb(main):037:0* (a + b).sort.uniq == a.sort.uniq
    => true
    irb(main):038:0> (a + c).sort.uniq == a.sort.uniq
    => false
    

    【讨论】:

      【解决方案6】:

      我想考虑容器数组中其他数组的连续元素序列,并提出以下内容:-- 代码灵感来自 Sawa 的代码

      class Array
        def contain? other
         arr = self & other
         (arr.eql? other ) && ((self.index(arr.last) - self.index(arr.first)).eql?(other.size - 1))
        end
      end
      

      结果:--

      correct_combination = [1, 2, 3, 4, 5]
      [1, 5, 8, 2, 3, 4, 5].contain?(correct_combination) # => false
      [8, 10, 1, 2, 3, 4, 5, 9].contain?(correct_combination) # => true
      [1, 8, 2, 3, 4, 5].contain?(correct_combination) # => false
      

      【讨论】:

      • @orangechicken 你在找这个吗?
      • @AndrewGrimm 逻辑是1.容器和组合数组的交集应该等于组合,2.容器中组合的第一个元素的索引从容器中组合的最后一个元素的索引中减去必须相等组合的大小减一。请参阅答案中的示例。
      【解决方案7】:

      我会建议一个比较每个循环的 for 循环

      @out_of_order_elements = []
      
      for i in 0.. @array_size do
        unless submission_array[i] == @correct_combination[i]
          @out_of_order_ids.push(@submission_array[i])
        end
      end 
      

      【讨论】:

        【解决方案8】:

        也许<=> 就是您要找的。​​p>

        比较 - 如果此数组小于、等于或大于 other_array,则返回整数(-1、0 或 +1)

        a = [1, 2, 3, 4, 5]
        b = [1, 5, 8, 2, 3, 4, 5]
        c = [8, 10, 1, 2, 3, 4, 5, 9]
        
        puts a <=> b # => -1
        puts a <=> c # => -1
        puts a <=> a # => 0
        

        更新:没关系,只是注意到它不关心位置。

        puts a <=> a.reverse # => -1
        

        【讨论】:

          【解决方案9】:

          这是我能想到的最好的。所有的return 调用都有点难看,但如果是大型数组,它应该比进行字符串比较更快。

          class Array
            def same?(o)
              if self.size == o.size
                (0..self.size).each {|i| return false if self[i] != o[i] }
              else
                return false
              end
          
              return true
            end
          end
          
          a = [1,2,3,4,5]
          b = [1, 5, 8, 2, 3, 4, 5]
          c = [1, 2, 6, 4, 5]
          
          puts a.same?(a.reverse) # => false
          puts a.same?(a) # => true
          puts a.same?(b) # => false
          puts a.same?(c) # => false
          

          【讨论】:

          • 我现在明白我完全误解了这个问题。 Yossi Zach 似乎对each_cons 给出了正确答案。 :)
          • 你不需要在Ruby中显式写return true你可以写true
          【解决方案10】:

          一种非常快速的方法是简单地从另一个数组中减去一个数组并测试一个空数组。

          correct_combination = [1, 2, 3, 4, 5]
          yep = [8, 10, 1, 2, 3, 4, 5, 9]
          nope = [1, 8, 2, 3, 4]
          if correct_combination - yep == []
            puts "yep has all the values"
          end
          if correct_combination - nope == []
            puts "nope has all the values"
          end
          

          这种方法不关心位置所以删除!

          对不起...我也错过了问题的重点。没有意识到您正在寻找优先顺序。我在寻找一种解决方案来评估一个大数组是否包含另一个大数组的所有条目时遇到了这个问题。 .all?/include?方法需要很长时间才能完成。 祝你好运!

          【讨论】:

            【解决方案11】:

            您可以简单地将数组作为字符串进行比较:

            correct_combination = [1, 2, 3, 4, 5]
            yep = [8, 10, 1, 2, 3, 4, 5, 9]
            nope = [1, 5, 8, 2, 3, 4, 5]
            if yep.to_s.include?(correct_combination.to_s)
              puts "yep"
            end
            if nope.to_s.include?(correct_combination.to_s)
              puts "nope"
            end
            

            【讨论】:

            猜你喜欢
            • 2013-03-09
            • 1970-01-01
            • 2018-03-22
            • 1970-01-01
            • 1970-01-01
            • 2015-10-28
            • 2014-11-01
            • 1970-01-01
            相关资源
            最近更新 更多