Filter

Sometimes you want to do a .select + .reject.
some_array.select { cond1 }.reject { cond2 }`

Or filter:
some_array.filter { cond1 && !cond2 }

Cond = Struct.new(:meth, :arr)

def filter(ar,
           sel: Cond.new(:all?, [proc {true}]),
           rej: Cond.new(:all?, [proc {false}])
          )

  ar.filter {|*n|
    sel.arr.map {it.(*n)}.send(sel.meth) &&
      !rej.arr.map {it.(*n)}.send(rej.meth)
  }
end


# test it

ar = [*1..100] # some data

# some rules
sel = [
        proc { [3,7,11].include?(it) },
        proc { (12..14) === it }
      ]

rej = [
        proc { it.odd? },
        proc { it > 7 }
      ]

s,r = Cond.new(:any?, sel), Cond.new(:all?, rej)


# ..and the call

p filter [*1..100], sel: s, rej: r # [3, 7, 12, 14]

:all? :none? :one? :any? is supposed to be used in the Struct - (but anything goes.. no check.)

The method works on anything that responds to .map.