0

我有以下两个数组

a= [1,2,3,4]
b= [1,2]
c= [1,2,3,4,5]

我想要一个返回布尔值的方法,如下所示

a.<some_method>(b) #should return true 
b.<some_method>(c) #should return false

假设我使用include?它不起作用,因为它期望 b 作为另一个数组中的元素

目前我正在做类似以下的事情

b.all?{|x| a.include?(x) }

我想知道有没有更好/更快的方法,因为我的两个数组都有很大的长度

4

6 回答 6

9

只需检查从第一个数组中减去第二个数组的结果。

在你的情况下 B - A 将是空的,但 C - A 将是非空的......

于 2012-10-09T08:10:58.440 回答
6

在最简单的情况下,数组操作是好的。

但是对于广泛的情况,我认为您需要设置操作。您可以查看http://www.ruby-doc.org/stdlib-1.9.3/libdoc/set/rdoc/Set.html

就像你的情况一样,它应该是

a= [1,2,3,4].to_set
b= [1,2].to_set
c= [1,2,3,4,5].to_set

a.superset?(b)   # -> true
b.superset?(c)   # -> false
于 2012-10-09T08:17:58.243 回答
4

array & other_array 返回数组和其他数组之间的匹配元素并删除任何重复项。您可以创建一个布尔测试,通过将一个数组的唯一元素与两个组合数组的相交元素进行比较,来查看一个数组的所有元素是否都在另一个数组中。

a = [1,2,3,4,5]
b = [2,3,4,5]
c = [4,5,6,7]

# check if all items in one array are in another array

def all_items_in_array?(original_array, test_array)
    test_array.uniq == original_array & test_array
end

此方法将返回一个布尔值

all_items_in_array?(a,b) # true
all_items_in_array?(a,c) # false
all_items_in_array?(b,c) # false

并进行重复的布尔检查

def all_items_including_duplicates_in_array?(original_array, test_array)
    original_grouped = original_array.group_by{|item| item}.values
    test_grouped = test_array.group_by{|item| item}.values
    test_grouped == original_grouped & test_grouped
end
于 2014-05-15T04:40:17.343 回答
1

数组差异和 Set#subset?答案很好,但 OP 专门询问了速度。回答性能问题的最佳方法是实际计算不同方法的时间。救援基准:

require 'benchmark'
require 'set'

BIG = 10_000
N = 1_000_000
SLOW_N = 500

a = [1,2,3,4]
b = [1,2]
c = [1,2,3,4,5]

bigA = (1..BIG).to_a
bigB = bigA.dup
bigB.pop
bigC = bigA.dup << (BIG+1)

setA = a.to_set
setB = b.to_set
setC = c.to_set
bigsetA = bigA.to_set
bigsetB = bigB.to_set
bigsetC = bigC.to_set

puts RUBY_DESCRIPTION
Benchmark.bm(21) do |x|
  x.report('Array#-')     { N.times{ (b-a).empty?; (c-a).empty? } }
  x.report('Set#subset?') { N.times{ setB.subset?(setA); setC.subset?(setA) } }
  x.report('big Array#-')     { SLOW_N.times{ (bigB-bigA).empty?; (bigC-bigA).empty? } }
  x.report('big Set#subset?') { SLOW_N.times{ bigsetB.subset?(bigsetA); bigsetC.subset?(bigsetA) } }
  x.report('big all? Set#include?')  { SLOW_N.times{ bigB.all?{|x| bigsetA.include?(x)}; bigC.all?{|x| bigsetA.include?(x)} } }
end

结果表明,对于小型集,没有显着差异。对于大型的Set#subset?,大约快 20%:

ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-linux]
                            user     system      total        real
Array#-                 1.520000   0.000000   1.520000 (  1.518501)
Set#subset?             1.520000   0.000000   1.520000 (  1.533306)
big Array#-             2.180000   0.000000   2.180000 (  2.180390)
big Set#subset?         1.720000   0.000000   1.720000 (  1.724991)
big all? Set#include?   2.130000   0.000000   2.130000 (  2.142015)
于 2012-10-09T09:03:08.903 回答
0
arr = [a, b, c]
arr.reduce(:&)

将为您提供一致的元素

我也追求不一致的。

于 2018-04-10T11:40:31.550 回答
-1

你也可以这样做:

a = [1,2,3]
b = [2,4,6]
c = [2,3,4]

(a & b).any? or (a & b & c).any?
于 2012-10-09T08:20:35.580 回答