首页 > 解决方案 > 如何遍历列表并制作元素列表

问题描述

我正在尝试在 clojure 中转换逻辑函数。我希望用户能够输入(convert '(and x y z)生成(nor (nor x) (nor y) (nor z). 所以我正在创建一个包含第一个元素的列表nor,然后尝试创建在for循环时创建的其余元素列表。然而,for循环只是组合了所有列表,并保留了nor它的外部。我也想知道如何跳过列表中的第一个元素,但这不是我现在的优先事项。我对clojure有点陌生,不知道如何将所有列表返回到更大的列表中。notand函数与or问题无关。

(defn lookup
  "Look up a value, i, in map m and returns the result if it exists. 
  Otherwise returns i."
  [i m]
  (get m i i))

(defn makelist
    [l]
    (for[i[l]] (list 'nor i)))

(defn convert
  [l]
  (let [p1 (first l)]
    (cond
      (= p1 'not) (map (fn [i] (lookup i '{not nor})) l)
      (= p1 'or) (list 'nor (map(fn [i] (lookup i '{or nor})) l))
      (= p1 'and) (list 'nor (makelist l))
      :else (print "error"))))

我得到的输出是(nor ((nor (and x y z)))). 我想要的输出是(nor (nor and) (nor x) (nor y) (nor z). 我不想要,(nor and)但直到我能弄清楚如何跳过第一个元素,我只想能够将列表分开。

标签: clojure

解决方案


我可以看到两个问题:

  1. makelist(for [i [l]] ...)所以它只产生一个i绑定到整个传入列表的单个项目l——你想要的是(for [i l] ...)这样l处理每个元素,
  2. convert的子句 forand创建一个包含两个元素的列表:nor(makelist l)-- 你想要的结果是(cons 'nor (makelist l))这样你得到一个列表,nor其中第一个元素,然后是调用结果的所有元素makelist

我还没有检查其他两个部分convert是否有类似的错误,但是上面的两个更改(convert '(and x y z))会产生(nor (nor and) (nor x) (nor y) (nor z))


推荐阅读