[英]how to retrieve a string that is in the first position of a list that is a hash-map value
If I evaluate: 如果我评估:
(:content {:foo "bar" :biz "baf" :content ("Happy Happy Joy Joy")})
I get: 我得到:
java.lang.String cannot be cast to clojure.lang.IFn
If I wanted the "Happy Happy Joy Joy"
string, how do I get it? 如果我想要
"Happy Happy Joy Joy"
字符串,如何获得它?
In my case, the hash-map is what I have to work with... I didn't create the string value inside a list. 就我而言,哈希映射是我必须使用的...我没有在列表内创建字符串值。 I understand clojure considers it a function as it's in the calling position.
我知道clojure认为它是函数,因为它处于调用位置。
If you're defining that list literally in your code, you'll need to "quote" it so that it isn't evaluated as a function: 如果要在代码中按字面定义该列表,则需要对其进行“引用”,以免将其视为函数:
user=> (:content {:foo "bar" :biz "baf" :content '("Happy Happy Joy Joy")})
("Happy Happy Joy Joy")
The only difference here is the '
character before the opening list parenthesis. 唯一的区别是开头列表括号前的
'
字符 。 You could also use the list
function. 您也可以使用
list
功能。
If you want just the first item in the :content
list, you can then use first
: 如果只需要
:content
列表中的第一项,则可以使用first
:
user=> (first (:content {:foo "bar" :biz "baf" :content '("Happy Happy Joy Joy")}))
"Happy Happy Joy Joy"
What is typed that has to include quote ( '
) literals to prevent the error message you are getting will be different from what is being returned from a function that does not have to have quotes in it. 为防止收到错误消息而必须包含引号(
'
)文字的类型与从不需要引号的函数返回的类型有所不同。 So just play with it a bit for the real (non REPL) case. 因此,请针对实际(非REPL)案例进行一些尝试。
(def x '(:content {:foo "bar" :biz "baf" :content '("Happy Happy Joy Joy")}))
(-> x second :content second first)
;;=> "Happy Happy Joy Joy"
For the real case (-> x second :content first)
might be what you want, where of course x
is the function call. 对于实际情况
(-> x second :content first)
可能是您想要的,当然x
是函数调用。
If as you say it is only the hash-map ( m
) you are concerned with then (-> m :content first)
should do the trick. 如果您只是说要关注的哈希映射(
m
),那么(-> m :content first)
应该可以解决问题。
One solution to the mismatch between the REPL and reality is to just use vectors instead of lists: 解决REPL与现实之间不匹配的一种方法是只使用向量而不是列表:
(def x [:content {:foo "bar" :biz "baf" :content ["Happy Happy Joy Joy"]}])
Here (-> x second :content first)
will indeed work. 在这里
(-> x second :content first)
确实可以工作。
The other answers did not fully clarify the effect of quote
. 其他答案并未完全阐明
quote
的作用。 Please see this code: 请查看以下代码:
(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))))
So, data-1
shows we can quote the entire expression at the outer level, and data-2
shows we can also quote each list expression (stuff in parens) to suppress the "function call" interpretation of a "list" type in Clojure. 因此,
data-1
显示我们可以在外部级别引用整个表达式,而data-2
显示我们也可以引用每个列表表达式(以括号为单位)以抑制Clojure中“列表”类型的“函数调用”解释。
data-3
shows that the single-quote char '
is just short for the special form (quote ...)
in Clojure. data-3
表明,单引号char '
只是Clojure中特殊形式(quote ...)
缩写。
Once you get the data literal form right, we see that data-1
and data-2
and data-3
actually result in identical data structures after being processed by the reader. 一旦正确获得了数据文字形式,我们就会看到
data-1
和data-2
和data-3
在被阅读器处理后实际上产生了相同的数据结构。
The last 3 tests show the proper syntax for extracting the string of interest from any of the 3 data structures. 最近的3个测试显示了从3个数据结构中的任何一个提取感兴趣的字符串的正确语法。
PS The testing stuff dotest
and is=
is from the Tupelo library . PS测试内容
dotest
和is=
来自Tupelo库 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.