【问题标题】:how to retrieve a string that is in the first position of a list that is a hash-map value如何检索位于作为哈希映射值的列表的第一个位置的字符串
【发布时间】:2017-11-28 02:03:02
【问题描述】:

如果我评估:

(:content {:foo "bar" :biz "baf" :content ("Happy Happy Joy Joy")})

我明白了:

java.lang.String cannot be cast to clojure.lang.IFn

如果我想要"Happy Happy Joy Joy" 字符串,我该如何获得它?

就我而言,哈希映射是我必须使用的...我没有在列表中创建字符串值。我知道 clojure 认为它是一个函数,因为它处于调用位置。

【问题讨论】:

  • 您提到您正在获取此列表作为库的返回值,那么您用于将此列表放入地图中的代码在哪里?

标签: clojure lisp clojurescript


【解决方案1】:

如果您在代码中逐字定义该列表,则需要“引用”它,以便它不会被评估为函数:

user=> (:content {:foo "bar" :biz "baf" :content '("Happy Happy Joy Joy")})
("Happy Happy Joy Joy")

这里唯一的区别是开头列表括号之前的' character。您也可以使用list 函数。

如果您只想要:content 列表中的第一项,则可以使用first

user=> (first (:content {:foo "bar" :biz "baf" :content '("Happy Happy Joy Joy")}))
"Happy Happy Joy Joy"

【讨论】:

  • 不幸的是,该列表是我正在使用的库的返回值,我无法整理。
  • 我认为您可能会被 REPL 中打印的列表值与您可以在 REPL 中评估的值之间的差异所困扰。列表用括号 (...) 简单地打印,但如果您尝试在 REPL 中逐字评估该列表,它会将带括号的形式解释为函数调用。
  • 嗯...我会考虑的。我正在尝试将括号中的字符串取出以在我的代码中的其他地方用作字符串。
【解决方案2】:

键入的内容必须包含引号 (') 文字以防止您收到错误消息,这与从不需要引号的函数返回的内容不同。所以在真实(非 REPL)的情况下稍微玩一下。

(def x '(:content {:foo "bar" :biz "baf" :content '("Happy Happy Joy Joy")}))

(-> x second :content second first)
;;=> "Happy Happy Joy Joy"

对于真实情况,(-> x second :content first) 可能是您想要的,当然x 是函数调用。

如果你说它只是你关心的哈希映射 (m),那么(-> m :content first) 应该可以解决问题。

REPL 与现实不匹配的一种解决方案是只使用向量而不是列表:

(def x [:content {:foo "bar" :biz "baf" :content ["Happy Happy Joy Joy"]}])

这里(-> x second :content first)确实可以工作。

【讨论】:

  • 由于建议使用向量而不是列表而被投票
【解决方案3】:

其他答案并没有完全阐明quote 的效果。请看这段代码:

(ns tst.demo.core
  (:use tupelo.test)
  (:require
    [tupelo.core :as t] ))

; Note:
; (def data {:foo "bar" :biz "baf" :content ("Happy Happy Joy Joy")})
;   => exception

(def data-1       '{:foo "bar" :biz "baf" :content  ("Happy Happy Joy Joy")})
(def data-2        {:foo "bar" :biz "baf" :content '("Happy Happy Joy Joy")})
(def data-3 (quote {:foo "bar" :biz "baf" :content  ("Happy Happy Joy Joy")}))
(dotest
  (is= data-1 data-2 data-3)
  (is= "Happy Happy Joy Joy" (first (:content data-1)))
  (is= "Happy Happy Joy Joy" (first (:content data-2)))
  (is= "Happy Happy Joy Joy" (first (:content data-3))))

所以,data-1 表明我们可以在外层引用整个表达式,data-2 表明我们还可以引用每个列表表达式(括号中的内容)来抑制“列表”的“函数调用”解释输入 Clojure。

data-3 表明单引号字符 ' 只是 Clojure 中特殊形式 (quote ...) 的缩写。

一旦你得到正确的数据字面量形式,我们就会看到data-1data-2data-3 在被阅读器处理后实际上会产生相同的数据结构。

最后 3 个测试显示了从 3 个数据结构中的任何一个中提取感兴趣的字符串的正确语法。


附:测试的东西dotestis=from the Tupelo library

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多