在抽象过滤器上操作(列表理解):组合两个过滤器

时间:2011-12-18 10:00:47

标签: filter lua set list-comprehension

简短而敏锐:
给定两个布尔语句,用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},
        },
    }
)

请指出正确的方向。

3 个答案:

答案 0 :(得分:3)

狂野猜测:将“过滤器”变为分离正常形式,并使用适当的方法减少(x == 8包含在x> 5中)。

答案 1 :(得分:2)

这可以通过某种方式实现这一目标。自评注的代码可以帮助您理解方法

#Create a Class Foo with attributes id and col
class Foo:
    def __init__(this,ID,COL):
        this.id=ID
        this.col=COL



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

#Create the Filter Functions
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)

#Create a list of filter functions
filters=[FilterX,FilterY,FilterZ]

#Create a set result (that will hold the intersected data) and assign the result of
#applying the First Filter on ObjList
result=set(filter(filters[0],ObjList))

#For the Rest of the filter's apply them on the ObjList, and then intersect
#the resultant set with the result
for s in (set(filter(foo,ObjList)) for foo in filters[1:]):
    result=result.intersection(s)

#Finally Display the result
[(obj.id,obj.col) for obj in result]

答案 2 :(得分:1)

我不知道我是否在这里错过了一个重点。根据“对象”的质量,您的过滤器似乎只返回一个布尔值。你为什么不用常规的“和”和“或”和函数来组成它们?

这就是我在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) -- returns true or false
intersection(filterX, filterY)(object) -- true or false

或者,如果您想经常重复使用它们:

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

filterXorY(object) -- true or false
filterXandY(object) -- true or false

我希望这会有所帮助。