Working with abstract filters (list comprehension): combining two filters

Short and sharp:
Given the two Boolean operators, what is the easiest way to compute the equation of their intersection in a language such as Lua?

Venn diagram
(Red = Filter 1, Blue = Filter 2, Purple = Intersection Area)

Long and crying:

  • Filter A : object.ID < 300

  • Filter B : object.ID < 600

Filter A is a subset of Filter B , that is: Filter B will contain everything that matches Filter A. strong>, plus 0 or more objects. In the Venn diagram, Filter A will be inside Filter B.

How can I calculate the equation of the intersection region?

More complex example:

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

Filter A crosses Filter B. On the Venn diagram, they will overlap. The equation for the overlapping region will be:
object.Col == 'GREEN' and (object.ID == 64 or object.ID > 9001)

How to calculate this equation in a language such as Python or Haskell?

I want to end up doing this in Lua, but if Python, Haskell, or another language provided functionality, I could look at the source code and convert it.

This is how I present filters in Lua:

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

Please point me in the right direction.

+4
source share
3 answers

Wild hunch: Bring the "Filters" into disjunctive normal form and reduce them using the appropriate methods (x == 8 contained in x> 5).

+3
source

It is somehow you can achieve this. Coded code helps you understand the approach.

 #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 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
source

I don’t know if this is an important point. It seems that your filters just return a boolean depending on the properties of the "object". Why don't you just use the regular "and" and "or" and perform their functions?

This is how I will make your filters in 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 

You can define the "union" or "intersection" of these filters with these additional functions:

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

And here is how you compose:

 union(filterX, filterY)(object) -- returns true or false intersection(filterX, filterY)(object) -- true or false 

Or, if you want to reuse them often:

 filterXorY = union(filterX, filterY) filterXandY = intersection(filterX, filterY) filterXorY(object) -- true or false filterXandY(object) -- true or false 

Hope this helps.

+1
source

Source: https://habr.com/ru/post/1386910/


All Articles