操作抽象过滤器(列表推导式):组合两个过滤器。

简短而有力:

在 Lua 这类语言中,给定两个布尔语句,最简单的方法是计算它们的交集方程是什么?

Venn Diagram

(红色 = 过滤器 1,蓝色 = 过滤器 2,紫色 = 相交区域)

冗长而哀叹:

  • 过滤器 A: object.ID < 300

  • 过滤器 B: object.ID < 600

过滤器 A过滤器 B 的一个 _子集_,也就是说:过滤器 B 包含了所有被 过滤器 A 匹配的对象,还有 0 个或多个对象。在一个维恩图中,过滤器 A过滤器 B 里面。

如何计算相交区域的方程?

更复杂的例子:

  • 过滤器 X: object.Col == 'GREEN' and (object.ID == 2 or object.ID == 64 or object.ID > 9001)
  • 过滤器 Y: (object.Col == 'RED' or object.Col == 'GREEN') and (object.ID == 3 or object.ID > 22)

过滤器 A过滤器 B 相交。在维恩图上,它们会重叠。相交区域的方程为:

object.Col == 'GREEN' and (object.ID == 64 or object.ID > 9001)

在 Python 或 Haskell 等语言中,如何计算这个方程?

我希望最终在 Lua 中实现这个功能,但如果 Python、Haskell 或其他语言提供了这个功能,我就能查看源代码并进行转换。

这是我在 Lua 中表示过滤器的方式:

filter = DataFilter(
    {"and",
        {"or",
            {"==", "Col", "RED"},
            {"==", "Col", "GREEN"},
        },
        {"or",
            {"==", "ID", 3},
            {">" , "ID", 22},
        },
    }
)

请指引我正确的方向。

原文链接 https://stackoverflow.com/questions/8551002

点赞
stackoverflow用户616486
stackoverflow用户616486

野猜想:将“过滤器”转化成析取范式并使用适当的方法进行简化(x == 8 包含在 x > 5 中)。

2011-12-18 10:16:41
stackoverflow用户977038
stackoverflow用户977038

这是一种实现方式。逐行注释的代码将帮助你理解该方法。

#创建一个名为Foo的类,有id和col两个属性
class Foo:
    def __init__(this,ID,COL):
        this.id=ID
        this.col=COL

#数据集
data=["VIOLET","INDIGO","BLUE","GREEN","YELLOW","ORANGE","RED"]
ObjList=[Foo(random.randint(1,70),random.choice(data)) for i in xrange(1,10000)]

#创建过滤函数
def FilterX(obj):
    return obj.col == 'GREEN'  and (obj.id == 2 or obj.id == 64 or obj.id > 9001)

def FilterY(obj):
    return (obj.col == 'RED' or obj.col == 'GREEN') and (obj.id == 3  or obj.id > 22)

def FilterZ(obj):
    return obj.col == 'GREEN'  and (obj.id > 50)

#创建一个包含过滤函数的列表
filters=[FilterX,FilterY,FilterZ]

#创建一个结果集合(将保存相交的数据),并将第一个过滤器应用到ObjList的结果分配给它
result=set(filter(filters[0],ObjList))

#对于剩下的过滤函数,先将它们应用到ObjList,然后将结果集合与结果相交
for s in (set(filter(foo,ObjList)) for foo in filters[1:]):
    result=result.intersection(s)

#最后显示结果
[(obj.id,obj.col) for obj in result]
2011-12-18 11:25:32
stackoverflow用户312586
stackoverflow用户312586

我不确定我是否漏了一个重要的点。看起来你的过滤器只是根据 "object" 的特性返回一个布尔值。为什么不只是使用常规的 "and" 和 "or",以及函数来组合它们呢?

这是我如何在 Lua 中创建你的过滤器的方式:

function filterX(object)
  return object.Col == 'GREEN' and
    (object.ID == 2 or object.ID == 64 or object.ID > 9001)
end

function filterY(object)
   return (object.Col == 'RED' or object.Col == 'GREEN') and
     (object.ID == 3 or object.ID > 22)
end

你可以用以下额外的函数定义这些过滤器的 "并集" 或 "交集":

function union(f,g)
  return function(...)
    return f(...) or g(...)
  end
end

function intersection(f,g)
  return function(...)
    return f(...) and g(...)
  end
end

以下是如何组合:

union(filterX, filterY)(object) -- 返回 true  false
intersection(filterX, filterY)(object) -- 返回 true  false

或者,如果你想经常重用它们:

filterXorY = union(filterX, filterY)
filterXandY = intersection(filterX, filterY)

filterXorY(object) -- 返回 truefalse
filterXandY(object) -- 返回 truefalse

希望这有所帮助。

2011-12-18 15:44:18