续集宝石身份/自然元素

时间:2016-12-21 14:14:53

标签: ruby sequel

我正在尝试使用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>,但我不确切知道它有什么影响。这是我要找的吗?

2 个答案:

答案 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 }