【问题标题】:In clojure, why doesn't "some" function work consistently on collections?在 clojure 中,为什么“某些”功能不能在集合上始终如一地工作?
【发布时间】:2014-07-10 03:29:46
【问题描述】:

对于下面,为什么最后一个返回零?函数“some”不适用于列表列表?

(some #(= % 1) '(1 3)     )  ; ==> true
(some #(= % '(1 3)) ['(1 3) '(1 2 3)]    )  ; ==> true
(some #(= % '(1 3)) '('(1 3) '(1 2 3))   )  ;==> nil 

【问题讨论】:

  • '(1 3) =/= '(quote (1 3))
  • 看看Replace elements in nested quoted lists adds new elements?。在那种情况下,症状是不同的,但'(... '(...) ...) 的含义的解释是您需要的,它包含在其中。
  • 另外,试试(注意双引号):(some #(= % ''(1 3)) '('(1 3) '(1 2 3))).

标签: list clojure lisp


【解决方案1】:

你应该像这样修改表达式:

(some #(= % '(1 3)) '((1 3) (1 2 3))   )
=> true

您已经使用'引用了该列表,您不需要在引用的列表中再次引用。

您可以轻松检查 REPL 中发生了什么:

user=> '((1 3) (1 2 3))
((1 3) (1 2 3))
user=> '('(1 3) '(1 2 3))
((quote (1 3)) (quote (1 2 3)))

【讨论】:

    【解决方案2】:

    @凯文

    我看到@ntalbs 回答了,但我习惯于测试各种时间。您可能会好奇地注意到我观察到的时差:

    (time (some #{'(1 3)} '((1 3) (1 2 3))))      ;0.073
    (time (some #(= % '(1 3)) '((1 3) (1 2 3))))  ;0.632
    
    (time (nil? (some #{'(1 3)} '((1 3) (1 2 3)))))     ;0.068
    (time (nil? (some #(= % '(1 3)) '((1 3) (1 2 3))))) ;0.628
    

    如果您正在处理大量数据,这可能是有用的知识

    【讨论】:

    • 谢谢@Frank!这非常有用。使用“nil”作为函数的一部分的理由是什么?我在我的机器上没有看到太大的性能差异。
    • 知道了! “零?”返回真或假
    【解决方案3】:

    正如 ntalbs 指出的,这里的问题是双引号。使用向量而不是列表或使用list 构建列表可能是一个更好的主意。两者都会为您节省一些混乱,并且向量具有不同的性能特征(接近恒定的随机访问时间)。

    (some #(= % '(1 3)) [[1 3] [1 2 3]])
    (some #(= % '(1 3)) (list (list 1 3) (list 1 2 3)))
    

    【讨论】:

    • 谢谢,但为什么 (= [1 3]'(1 3)) 评估为真?向量与列表相同??
    • 因为它们都是序列。 = 的文档说:“与 Java x.equals(y) 相同,但它也适用于 nil,并以与类型无关的方式比较数字和集合”
    猜你喜欢
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    • 2017-12-06
    • 1970-01-01
    • 2010-10-24
    相关资源
    最近更新 更多