【问题标题】:member? function on infinite lists成员?无限列表上的函数
【发布时间】:2015-10-25 10:21:38
【问题描述】:

我实现了一个成员? clojure中的函数如下:

(defn member? [item seq]
  (cond (empty? seq) false
        (= item (first seq)) true
        :else (recur item (rest seq))))

不幸的是,这不适用于无限列表。有谁知道实现它的方法以便能够获得:

(member? 3 (range)) -> true

【问题讨论】:

  • 为什么不直接使用filter?例如(boolean (seq (filter #{2} (range 10))))
  • 即使它适用于阳性病例,您认为(member? -10 (range)) 应该返回什么?
  • @alfredx 这只是一个测试用例:我想确定 member 的第二个参数?出于性能原因并没有完全实现,尽管在实践中我永远不会提供无限的列表。我不知道它确实在 clojure 1.7.0 中工作(我已经用 clojure 1.6.0 进行了测试,请参阅下面的评论)。
  • 我觉得这是XY problem。当用户尝试移植 unique 函数以处理惰性序列时,我之前曾看到过这样的问题。
  • 顺便说一句,我极力劝阻您不要使用“seq”(或任何其他会隐藏 clojure.core 中的函数的名称)作为变量名。它有效,但极易出错。

标签: recursion clojure lazy-evaluation


【解决方案1】:

对于无限输入序列,您的实现行为正确。在找到元素之前它不会终止,因为(empty? seq) 的情况永远不会失败。

考虑在无限空间中搜索某物。什么时候是说它不存在的好时机?没有可靠的方法来判断。限制您搜索的空间,例如。 g.:

(member? 3 (take 10 (range)))

【讨论】:

    【解决方案2】:

    你不能。我的意思是,完全没有。

    为了确保没有特定元素,您需要遍历整个集合。只有这样,你才能保证它不存在。

    在某些情况下,例如您的示例,输入序列是升序的,即。 e.序列中的每个元素都小于其连续元素。您可以利用它并使您的序列有限using take-while

    (member? 3    # is 3 a member of
      (take-while # a sequence of elements
        #(<= % 3) # up to 3 inclusively
        range))   # from range
    

    【讨论】:

      【解决方案3】:

      对我来说,您的代码已经有效:(member? 3 (range)) 返回true

      但是检查无限序列中的值是否存在有什么意义呢?它要么返回 true,要么永远不会返回。

      【讨论】:

      • 感谢您的来信!我的原始代码是用 clojure 1.6.0 测试的。在 clojure 1.7.0 中它确实有效。问这个问题是因为我想确定,我的成员的第二个论点?由于性能原因,功能并不总是完全实现。我想发布一些代码来说明这一点,但不幸的是,降价似乎不起作用,而且代码几乎不可读,所以我会避免这样做,直到我完全理解为什么 4 个缩进空格和 2 个空格cmets 中的行尾不会导致正确损坏的代码块...
      • 它也可以在 Clojure 1.6 中使用。你一定犯了其他错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-12
      • 1970-01-01
      • 2011-08-22
      • 2015-04-19
      • 2014-05-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多