【问题标题】:how to use Conj function in Clojure如何在 Clojure 中使用 Conj 函数
【发布时间】:2013-11-07 04:20:21
【问题描述】:

我正在尝试在我的程序中实现其中一项功能。我在 func3 中有 list=[a b c] 作为参数。我想测试这些项目的相等性。如果它们不相等,我将使用 func2 的另一个列表返回再次调用它。 这是我需要做的。我希望 Conj 执行此操作 [list list1 list2 list3] 直到 func3 具有相等的项目。在我的函数中,我希望 conj 在条件为假时将一个空向量 r[] 合并到其他列表。我现在得到的只是条件为真时的最终列表返回。假设条件必须为假(项目不相等)才能为真。有人可以帮我在错误的条件下使用 conj。谢谢。

   ;input [1 2 3]
   ;output [[1 2 3][1 3 4] [3 4 5] ]// numbers for demo only
   (defn func3 [list]
       (loop [v (vec list) r []]
        (if(= (v 0) (v 1) (v 2))        
            (conj r v)
            (let[result (func2 v)]
            ;i want to merge result to r until the condition is true
            (conj r result)
            (func3 result)))))

【问题讨论】:

  • 说真的,你必须更好地描述你的函数应该做什么。给它一个比func3 更有意义的名字将是一个开始。然后我想知道您的函数如何返回包含不相等项和多个项的列表。
  • 这就是我想要做的。 func3 将确定 [1 2 3 4] 中的项目是否相等。如果没有,func2 将计算一个新列表并返回到 func3。 func3 再次执行它的工作,直到它在列表中找到相等的项目。我想打印 func2 的每次计算的结果,包括初始列表。你觉得这有意义吗?

标签: clojure


【解决方案1】:

Conj 永远不会改变它的输入,它会根据输入创建一个新的输出。在第二种情况下,你没有对 conj 的输出做任何事情,所以它的结果永远不会被使用。

 (defn func3 [list]
       (loop [[v & vs] (vec list) r []]
        (if (= (v 0) (v 1) (v 2))        
            (conj r v)
            (let [result (func2 v)
                  r (conj r result)]
              (recur vs r)))))

【讨论】:

  • 该函数的输入/输出是什么?
  • 好点,我只是在解决关于 conj 的问题,显然这里还有更多问题(比如循环被使用,好像它被允许一样)我认为这里缺少重复出现,但我没有不知道去哪儿了。
  • 根据问题中的评论进行了更新,以便在适当的地方重复出现
  • 这就是为什么我使用 r[] 来合并结果。稍后返回 r。我在控制台中尝试了这个,它可以工作:(def x (conj x [1 2]))。这将返回 X 作为 [[1 2] [1 2]]
  • 是的,因为那个绑定了输出,只使用conj并没有绑定结果,它需要一个你可以参考的绑定。 r [] 也是一个循环绑定,但你没有重复循环,所以除了初始化之外没有任何值进入那里,并且在 func3 上显式 recur 没有使用 conj 输出。
【解决方案2】:

我知道您有一个包含三个元素的列表作为初始输入,想要比较它们是否相等。如果它们匹配,您希望将列表附加到稍后返回的累加器 - 如果它们不匹配,您希望使用惯用称为 func2 的函数转换列表并再次尝试该过程。

编辑:既然你已经评论了你的函数应该如何工作,这里有一个实现:

(defn func3
  "Determines whether items in coll are equal. If not, transforms coll with func2 and
   repeats the test until a coll with equal elements could be found. 

   Returns a vector of all tried versions."
  [coll]
  (loop [acc []
         coll coll]
    (if (apply = coll)
      (conj acc coll)
      (recur (conj acc coll)
             (func2 coll)))))

这是一个惰性实现:

 (defn func3
   [coll]
   (-> (->> coll
            (iterate func2)
            (split-with (partial apply =)))
       (as-> [dropped [r]]
             (concat dropped [r])))

【讨论】:

    猜你喜欢
    • 2011-03-01
    • 1970-01-01
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 2017-12-28
    • 1970-01-01
    • 2013-11-21
    • 2014-01-15
    相关资源
    最近更新 更多