简体   繁体   English

如何检索位于哈希映射值列表的第一位置的字符串

[英]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-1data-2data-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测试内容dotestis= 来自Tupelo库

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM