红宝石轨道包括?数组



是否可以检查数组内的包含数组?

我想检查是否

primary = [1,2,3]包括secondary = [2,3]

我试过primary.include?(secondary) => false

需要返回布尔值

解决方案

没有重复项

如果没有任何重复项,您可以计算数组差异,并检查它是否为空:

(secondary-primary).empty?
#=> true

一般情况

subset_of?检查对于secondary中的每个唯一元素,primary中至少有同样多的元素:

class Array
  def count_by
    each_with_object(Hash.new(0)) { |e, h| h[e] += 1 }
  end
  def subset_of?(superset)
    superset_counts = superset.count_by
    count_by.all? { |k, count| superset_counts[k] >= count }
  end
end

例:

secondary.subset_of?(primary)
#=> true
[2,2].subset_of?([1, 2, 3])
#=> false

这应该适用于任何数组,并且应该比大数组的其他答案更快。

测试

([1,2,3] - [3,4,5,2,1]).empty?
#=> true
([1,2,3,'a'] - [3,4,5,2,1]).empty?
#=> false
test = primary.dup
secondary.all? { |e| test.index(e).tap { |i| test.delete_at(i) if i } }
primary, secondary = [1, 2, 3], [2, 2]
#⇒ false
primary, secondary = [1, 2, 2, 3], [2, 2, 1]
#⇒ true

这里正在做什么:

  • 我们迭代secondary,声称所有块都应该返回true
  • 在每次后续迭代中,我们
    • 如果primary中没有此类元素,请立即返回false中断循环
    • 否则,我们改变 primary 的副本,删除已经检查的元素。

这里唯一的技巧是使用 Object#tap找到元素时始终返回trueprimary中的元素可能是falseyArray#delete返回已删除的元素,我们可能会意外返回falsey,在这种情况下错误地破坏循环。一旦找到元素,我们就应该true返回到all?循环中,因此tap .

验证这是到目前为止唯一正确答案的输入:

primary, secondary = [1, 2, 2, 3, nil, nil], [2, 2, 1, nil, nil]
#⇒ true
primary, secondary = [1, 2, 2, 3, nil], [2, 2, 1, nil, nil]
#⇒ false
primary = [1,2,3]
secondary = [2,3]
primary.each_cons(secondary.size).include?(secondary)

Enumerable#each_cons 获取数组的块,并为每个组迭代一个。
可枚举很棒!

阅读可枚举文档,我每次都能学到新东西。

a = [5, 1, 6, 14, 2, 8]
b = [2, 6, 15]
a - b
=> [5, 1, 14, 8]
b - a
=> [15]
#this is what you need
(b - a).empty?
=> false

Here 解决方案

primary=[1,2,3]  
secondary=[2,3]  
secondary.all? { |e| primary.include?(e) }

要检查另一个数组中是否存在一个数组,只需使用 include? 方法,

primary = [1,2,3,[1,2]]
secondary = [2,3]
result = primary.include? secondary
# returns false as [2,3] is not present
primary = [1,2,3,[1,2]]
secondary = [1,2]
result = primary.include? secondary
# returns true as [1,2] is present

要检查辅助数组的元素是否存在于主数组中,还要处理重复的元素:

result = (secondary.select {|i| secondary.count(i)<=primary.count(i)}.length == secondary.length)
primary, secondary = [1, 2, 3], [2, 2]
# returns false
primary, secondary = [1, 2, 2, 3], [2, 2, 1]
# returns true

a1 = [5, 3, 9, 7, 8, 7, 1, 7]

a2 = [1, 9, 5, 7, 5]

它将检查a2元素是否存在于a1中,

a2.all?{ |i| a1.include? i } #=> true

使用

secondary.all? { |e| primary.include?(e) }

使用交集

(primary & secondary).size == secondary.uniq.size

如果主元素中存在任何次要元素

(primary & secondary).present?

希望对你有帮助

最新更新