Ruby 数组包含x和其他元素

Ruby 数组包含x和其他元素,ruby,Ruby,是否可以确定数组是否包含特定值和其他值 array = [1, 1, 3, 4] array.include? 1 #=> true 我可以使用include?来确定它是否包含数字1,但在这之后,我如何检查它是否包含除1以外的值,而不管这些值是什么?您可以编写如下方法 def any_other_value_present? number, array !!(array - [ number ]).empty? end 您可以将元素的数量与出现的1进行比较: array = [1

是否可以确定数组是否包含特定值和其他值

array = [1, 1, 3, 4]

array.include? 1 #=> true

我可以使用
include?
来确定它是否包含数字
1
,但在这之后,我如何检查它是否包含除
1
以外的值,而不管这些值是什么?

您可以编写如下方法

def any_other_value_present? number, array
  !!(array - [ number ]).empty?
end

您可以将元素的数量与出现的
1
进行比较:

array = [1, 1, 3, 4]
p array.count(1) == array.size #true if only 1 are in array (or empty)
p array.count(1) != array.size #True if other values are available,

您可以使用一个相当简单的迭代器来完成此任务。比如说,

array = [1,1,3,4]
puts array.any? { |val| 1 != val }
=> true

因此,如果数组中除了
1
之外还有其他内容,则返回true

可能有很多方法可以更好地回答这个问题,但是如果不了解如何使用这些信息的更广泛背景,就很难给出准确的答案

也就是说,你有很多选择。我不确定是否有一个单一的操作可以测试这一点,但一个聪明的解决方案可能是:

array.chunk {|v| v == 1 }.to_a.length == 2
这将返回一个块结果数组和匹配这些块结果的值。如果该数组的长度为2,则您知道该数组既有匹配的值,也有不匹配的值
1

但这是Θ(n);您可以使用多段代码实现更快的解决方案,例如:

array.include?(1) && array.any? {|v| v != 1}

如果你需要两个布尔人,我会这样做

a = [1,2,3,4,5]
has_one,and_others = a.partition{|n| n == 1}.map(&:any?)
has_one
#=> true
and_others
#=> true
a = [1,1,1,1,1]
has_one,and_others = a.partition{|n| n == 1}.map(&:any?)
has_one
#=> true
and_others 
#=> false

#分区
将数组分成两个数组,第一个是块为真,第二个是块为假。

以下是一些基准测试:

require 'fruity'

array = [1, 1, 3, 4]

compare do
  chunk_it { array.chunk {|v| v == 1 }.to_a.length == 2 }
  include_and_any { array.include?(1) && array.any? {|v| v != 1} }
  set_diff { !!(array - [ 1 ]).empty? }
  array_count { array.count(1) == array.size }
  partition_them { has_one,and_others = array.partition{|n| n == 1}.map(&:any?); has_one && and_others }
end

# >> Running each test 16384 times. Test will take about 5 seconds.
# >> array_count is faster than include_and_any by 4x ± 0.1 (results differ: false vs true)
# >> include_and_any is faster than set_diff by 19.999999999999996% ± 10.0% (results differ: true vs false)
# >> set_diff is faster than partition_them by 2x ± 0.1 (results differ: false vs true)
# >> partition_them is faster than chunk_it by 5x ± 1.0
请注意,其中一些返回的结果与其他结果不同。

如何:

class Array

def include_any?(*args)
    args.each {|value| return true if include?(value) }
    return false
end

def includes?(*args)
    args.each {|value| return false unless include?(value)}
    return true
end
end


myarray = [:dog, :cat, :cow, :sheep]

#This Will Check if includes all the values given
myarray.includes?(:dog, :cat)
=> true

myarray.includes?(:dog, :horse)
=> false

# This will check if include any of the values given
myarray.includes_any?(:dog, :cat, :horse)
=> true

myarray.includes_any?(:horse, :ox)
=> false

我用一个不同的数组和下面显示的另外四种方法重新运行@theTinMan的基准测试:
index
uniq
delete
dup\u delete
。注意
delete
会对数组进行变异

每一轮的结果差别很大,但是
include_和_any
通常仍然以令人满意的优势获胜。另外,请注意,
furty
(我以前没有使用过)报告说,完成某些运行需要几分钟,但实际上所需时间不会超过15秒

require 'fruity'

def run_em(array, val)
  compare do
    chunk_it        { array.chunk {|v| v == val }.to_a.length == 2 }
    include_and_any { array.include?(val) && array.any? {|v| v != 1} }
    set_diff        { !!(array - [ val ]).empty? }
    array_count     { array.count(val) == array.size }
    partition_them  { has_one,and_others = array.partition{|n| n == 1}.map(&:any?)
                      has_one && and_others }
    index           { !!(array.index(val) && array.index { |e| e != val }) }
    uniq            { a = array.uniq; a.include?(val) && (a.size > 1) }
    delete          { !!array.delete(val) && array.any? }
    dup_delete      { a = array.dup; !!a.delete(val) && a.any? }
  end
end
测试阵列

n = 1_000
only_dups = Array.new(n,0)
all_dups_but_one = only_dups.dup
all_dups_but_one[n/2] = 1
仅重复

n = 1_000
only_dups = Array.new(n,0)
all_dups_but_one = only_dups.dup
all_dups_but_one[n/2] = 1
仅重复,第一次运行

仅重复,第二次运行

除一份外,所有副本

除一个外的所有重复项,第一次运行

除第二次运行外的所有重复项


这对于一个数字数组来说是行不通的,就像OP的例子一样。很好。我换了一种不同的迭代方法,这样它现在就可以工作了。为什么不使用
all?
而不是
=例如
array.all?{| val | val==1}
因为
all?
any?
的反义词,类似的东西可能也会起作用,尽管我自己没有尝试过,我也不认为我曾经使用过
all?
。从各种各样的答案中可以看出,解决问题的方法总是不止一种。
all?
不是
any?
的反义词<代码>任何?
一旦有一个匹配项,就会停止检查<代码>全部?必须遍历整个数组以检查每个元素。两者在速度上可能存在巨大差异。我会编写
array。任何{I}I==1}&&array。任何{I}I!=1}I=>true
,但根据一个基准测试
include?
会使它快50%。第二个不仅更快,它以一种非常容易理解的方式表达了这个问题。@theTinMan在任何时候你都可以避免块绑定和调用,通常你会看到速度的提高。
[array-[number])
应该是
(array-[number])
@theTinMan谢谢..忽略了返回的值是向后的。你需要在某个地方使用
run_em(only_dups, 0)

Running each test 65536 times. Test will take about 13 seconds.
include_and_any is similar to delete
delete is similar to index
index is faster than uniq by 2x ± 1.0
uniq is similar to array_count (results differ: false vs true)
array_count is faster than dup_delete by 3x ± 1.0 (results differ: true vs false)
dup_delete is faster than set_diff by 2x ± 0.1 (results differ: false vs true)
set_diff is similar to partition_them (results differ: true vs false)
partition_them is faster than chunk_it by 7x ± 1.0
run_em(all_dups_but_one, 0)

Running each test 32768 times. Test will take about 4 minutes.
include_and_any is faster than index by 2x ± 1.0
index is similar to delete
delete is similar to uniq
uniq is faster than array_count by 2x ± 0.1
array_count is faster than dup_delete by 2x ± 0.1
dup_delete is faster than set_diff by 2x ± 0.1
set_diff is faster than partition_them by 2x ± 0.1
partition_them is faster than chunk_it by 6x ± 1.0
run_em(all_dups_but_one, 0)

Running each test 65536 times. Test will take about 12 seconds.
include_and_any is faster than index by 2x ± 1.0
index is similar to delete
delete is similar to uniq
uniq is faster than array_count by 2x ± 1.0
array_count is faster than dup_delete by 2x ± 1.0
dup_delete is faster than set_diff by 2x ± 0.1
set_diff is similar to partition_them
partition_them is faster than chunk_it by 6x ± 1.0