list - 如何删除包含两个您不想要的元素的列表中的元素?

标签 list loops lisp common-lisp

(defun combinations (&rest lists) (if (car lists) (mapcan (lambda (in-val) (mapcar (lambda (out-val) (cons out-val in-val)) (car lists))) (apply #'combinations (cdr lists))) (list nil)))

This function makes a combination of any number of lists.

(defun main()
  (setq m-list (combinations '(Blacket Bluet Browning Greenfield Whitehall) '(four-leaf-clover penny rabbit-foot ribbon silver-dollar) '(center-field first-base right-field short-stop third-base)))

  (setq constraints  (list '(Browning penny) '(Browning silver-dollar) '(Browning right-field) '(Browning center-field) '(Bluet center-field) '(Bluet right-field) '(Greenfield first-base) '(Greenfield short-stop)
    '(Greenfield third-base) '(Whitehall center-field) '(Whitehall right-field) '(Greenfield four-leaf-clover) '(Greenfield penny) '(Whitehall four-leaf-clover) '(Whitehall penny) 
    '(Blacket four-leaf-clover) '(Blacket penny) '(Blacket first-base) '(Blacket third-base) '(Blacket ribbon) '(Bluet ribbon) '(center-field rabbit-foot)))
  (loop  
    (print m-list)
    (setq n-constraint (car constraints))
    (setq m-list (remove-it m-list n-constraint))
    (setq constraints (cdr constraints))
    (when (null constraints) (return m-list))))

The main function creates two lists, a list of all the possible combinations of players, charms, and positions, and a list of constraints, where two variables in each constraint list cannot be together. I then created a loop in order to take one constraint each iteration and remove from the main list of combinations the combination that matches what the constraint says should not exist.

(defun remove-it (x y) 
    (if (and (not (eq (find (nth 0 y) (car x)) nil) (not (eq (find (nth 1 y)(car x)) nil)))) (setq x (remove (car x) x :test #'equal)))
    (return x))

For some reason the remove-it function only manages to remove everything related to the constraint. For example, a constraint is (Browning penny). The intention is to remove any list inside the massive combinations list that contains the two elements Browning and penny together. However, the function seems to remove every list that contains Browning separately and penny. I only want the function to remove lists that have Browning and Penny together.

最佳答案

让我们从缩进您的 remove-it 函数开始:

(defun remove-it (x y) 
  (if (and (not (eq (find (nth 0 y) (car x)) nil)
                (not (eq (find (nth 1 y)(car x)) nil))))
      (setq x (remove (car x) x :test #'equal)))
  (return x))

从函数的角度来看,这是相当荒谬的。 not 函数通常只接受一个参数,您(很可能)在第一个 not 调用后缺少右括号。

您还只检查了 x 的第一个元素,所以如果没问题,您就不会检查列表的其余部分。

您的变量名称不太清楚(“x”和“y”的实际含义)。

您不需要显式返回,只需将 x 作为最后的单个表达式即可。

一个可能更好的解决方案可能是(基于我对您实际想要做的事情的理解,即“收集所有没有两个被禁止组合的组合”):

(defun remove-constrained-combinations (combinations constraint-1 constraint-2)
  (loop for combo in combinations
        unless (and (member constraint-1 combinations)
                    (member constraint-2 combinations)
        collect combo))

关于list - 如何删除包含两个您不想要的元素的列表中的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37191938/

相关文章:

python - 在列表中查找项目索引

PHP - 执行长脚本时可能遇到的障碍

java - Clojure : java. lang.Character 无法转换为 clojure.lang.IFn

lisp - 在 Lisp 中,不同层次的含义

lisp - 请批评我的 Lisp

python - 列表中每个元组的第一个元素与字母字符之间的高效映射

r - 将函数参数的名称分配给内部列表

Javascript "document.getElementById"通配符循环?

Python - 字典未正确更新

list - Ant 中使用列表的并行作业