[erlang-questions] qlc expression help.

Adam Bozanich <>
Mon Feb 11 04:09:47 CET 2008


Hi all,

I'm having trouble creating a qlc expression which does what I want.  I'm
basically trying to create a filter for QH1 with a predicate that depends on
QH2.
In the example below, test2/0 gives me the result I'm looking for, but it
requires the second QH to be eval'd.  I'd like the expression to look like
what's in the test1/0 function.  Any suggestions?

Thanks,
-Adam

session:
8> test_qlc:test2().
[{1,6,7},{2,8,9}]
9> test_qlc:test1().
[{1,4,5},
 {1,2,3},
 {1,6,7},
 {1,6,7},
 {2,4,5},
 {2,2,3},
 {2,8,9},
 {2,8,9},
 {3,4,5},
 {3,2,3}]

code:

-module(test_qlc).
-include_lib("stdlib/include/qlc.hrl").
-export([test1/0,test2/0,handroll/0]).

-define(DB,[
  {1,4,5},{1,2,3},{1,6,7},
  {2,4,5},{2,2,3},{2,8,9},
  {3,4,5},{3,2,3}
]).
-define(OBJ,[{2,3},{4,5}]).

test1() ->
    qlc:eval(qlc:q([ {O1,C1,V1} ||
                       {O1,C1,V1} <- ?DB,
                       {C2,V2} <- ?OBJ,
                       C1 /= C2,
                       V1 /= V2])).
test2() ->
    qlc:eval(qlc:q([ {O1,C1,V1} ||
                     {O1,C1,V1} <- ?DB,
                     lists:member({C1,V1},?OBJ) == false ])).

handroll() ->
    S = mkset(?DB),
    O = mkobj(?OBJ),
    to_table(difference(O,related(O,S))).

related(S1,D) ->
    dict:filter(fun(_,S2) ->
                        sets:is_subset(S1,S2)
                end,D).

difference(S1,D) ->
    dict:filter(fun(_,S2) ->
                        sets:size(S2) > 0
                end,
                dict:map(fun(_,S2) ->
                                 sets:subtract(S2,S1)
                         end,D)).

to_table(D) ->
    lists:flatmap(fun({K,V}) ->
                          lists:map(fun({X,Y}) ->
                                            {K,X,Y}
                                    end,
                                    sets:to_list(V))
                  end,
                  dict:to_list(D)).

mkset(DB) ->
    dict:map(fun(_,V) ->
                     sets:from_list(V)
             end,
             lists:foldl(fun({O,C,V},Acc) ->
                                  dict:append(O,{C,V},Acc)
                         end,
                         dict:new(),DB)).

mkobj(OBJ) ->
    sets:from_list(OBJ).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20080210/74455c9d/attachment.html>


More information about the erlang-questions mailing list