我正在尝试使用reduce函数来连接多个续集表达式。然而,在开始时,我需要一个自然元素/身份元素Sequel-expression。即,在不改变查询含义的情况下可以& -connected的表达式。我尝试使用nil,但这似乎不起作用。有这样的事吗?^^
想象一下以下
def reduce(buffer, array, &func)
return buffer if array.empty?
if buffer.nil? # I basically want to get rid of this
reduce(array[0], array[1..-1], &func)
else
reduce(func.call(buffer, array[0]), array[1..-1], &func)
end
end
# to be able to call:
reduce(NATURAL_ELEMENT, array_of_expressions) { |first, second| first & second }
致电Sequel.expr(nil)
时,我得到#<Sequel::SQL::Wrapper @value=>nil>
,但我不确切知道它有什么影响。这是我要找的吗?
答案 0 :(得分:2)
你想要的是通用集,即包含所有可能元素的集合。这是集合交叉点的标识。如果您使用Sequel.expr(nil)
,则相当于空集。
我不知道续集中有任何通用集(或其他身份对象),但你可以尝试实现一个。这是一个例子(使用Singleton
模块进行测量):
require "singleton"
class UniversalSet
include Singleton
def &(other)
other
end
end
UNIVERSAL_SET = UniversalSet.instance
现在您可以在集交叉操作中使用它。元素的类型是无关紧要的,因此它也适用于SQL
个对象。
UNIVERSAL_SET & [1, 2, 3]
#=> [1, 2, 3]
如果您愿意,还可以为通用集实现其他设置操作。
然而,这具有不可交换性的缺点。如果您尝试逆向:[1, 2, 3] & UNIVERSAL_SET
会抛出错误。这是Ruby中可用的强制结构的限制。 (目前,您只能为数字交换运算符。)
答案 1 :(得分:2)
以下是something
的{{1}}:
something & Sequel.expr(field: 1) == Sequel.expr(field: 1)
你可以写:
class IdentityFunction
def self.&(b)
b
end
end
IdentityFunction & "test" #=> "test"
IdentityFunction & 3 #=> 3
请注意,reduce
默认将第一个元素作为起始值,因此甚至不需要[[1,2,3,4,5], [2,3,4], [3,4,5]].reduce(IdentityFunction){|a,b| a & b} #=> [3, 4]
:
IdentityFunction
这意味着你想要实现的目标可能写成:
[[1,2,3,4,5], [2,3,4], [3,4,5]].reduce{|a,b| a & b} #=> [3, 4]
或只是
array_of_expressions.reduce{ |first, second| first & second }