代码之家  ›  专栏  ›  技术社区  ›  Federico Ribero

获取不在第二个列表中的元素

  •  0
  • Federico Ribero  · 技术社区  · 7 年前

    我想做的是得到什么‘组件’没有被使用。所以我创建了一个包含所有“组件”和“在用组件”的列表。
    我的想法是比较这个列表,并创建另一个列表,其中包含不匹配的元素。

    component('name 1', 1).
    component('name 2', 2).
    component('name 3', 3).
    component('name 4', 4).
    component('name 5', 5).
    
    inUse(1, 'name 1').
    inUse(1, 'name 3').
    inUse(1, 'name 5').
    
    comp_list(L):- findall(Comp, component(Comp, _), L).
    inuse_list(L):- findall(Comp, inUse(_, Comp), L).
    

    member('name comp', List). 在这里,我可以用其他列表的每个元素替换“name comp”。

    提前谢谢。

    L1 = ['name 1', 'name 2', 'name 3', 'name 4', 'name 5'] %comp_list(L).
    L2 = ['name 1', 'name 3', 'name 5']                     %inuse_list(L).
    
    someRule(R):- comp_list(L1), inuse_list(L2),    %more code, to obtain a list R with:
    
    R = ['name 2', 'name 4'] (Elements lacking on inuse_list)
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Jan Wielemaker    7 年前

    虽然答案是正确的,但如果需要对数据库中的事实和规则进行推理,最好尽可能避免使用列表。在这种情况下,目标未使用组件很容易定义为

    ununsed(Name) :- component(Name, _), \+ inUse(_, Name).

    这很好地列举了未使用的组件。如果您想将它们列在列表中,请使用 findall/3 结束 unused/1 . 在大多数情况下,虽然 未使用/1 更容易与其他纯逻辑关系结合。

    在大多数情况下 聚合 基本体,如 findall/3 , aggregate/3 等,最好推迟到最后或根本不使用。

        2
  •  1
  •   coder    7 年前

    您可以添加一个简单的递归谓词来获取 comp_list 不属于 inuse_list :

    obtain_elements([],_,[]).
    obtain_elements([H|T],L,[H|T1]):-\+member(H,L),obtain_elements(T,L,T1).
    obtain_elements([H|T],L,L2):-member(H,L),obtain_elements(T,L,L2).
    

    使用方法如下:

    someRule(R):- comp_list(L1),
                  inuse_list(L2), 
                  obtain_elements(L1,L2,R).
    

    findall/3 谓语:

    someRule(R):- comp_list(L1),
                  inuse_list(L2), 
                  findall(X,(member(X,L1),\+member(X,L2)),R).