请在2024 状态 Clojure 调查中分享您的想法!

欢迎!请参阅“关于”页面以获取有关工作方式的更多信息。

0
序列

你好,在从文件读取字词并将其归约到映射后

{aabdgoo (abogado), aaceilmnotx (exclamation), ehpryz (zephyr), eirt (tire rite), ghirt (right)}

并然后进行筛选后,我有这个

([aabdgoo (abogado)] [aaceilmnotx (exclamation)] [eirt (tire rite)] [ghirt (right)])

我可以运行像valskeys这样的函数,以及对该结构进行进一步归约,没有任何问题。

我想要对每个向量中第二位的单词列表进行排序,并认为遍历这个结构会很简单,但经过数小时的迭代,我就是无法让它工作。

(map #('((first %) (second %))) input)在map的行上抛出执行错误 (ClassCastException)class clojure.lang.PersistentList cannot be cast to class clojure.lang.IFn (clojure.lang.PersistentList and clojure.lang.IFn are in unnamed module of loader 'app')

(map #([(first %) (second %)]) input)使工具抱怨Vector只能用1个参数调用,但是这里调用了: 0

(map #(vector (first %) (second %)) input)在几行之后调用keysmap输出:执行错误 (ClassCastException),抛出错误:class clojure.lang.PersistentVector cannot be cast to class java.util.Map$Entry (clojure.lang.PersistentVector is in unnamed module of loader 'app'; java.util.Map$Entry is in module java.base of loader 'bootstrap')

我不知道它在要什么。我做错了什么?

谢谢

1 答案

+1

您可以使用(into {} ...)将那对列表(向量)转换为映射(这同样允许您使用transducers,查看它们)。然后您将能够使用update-vals

(map #('((first %) (second %))) input) 抛出

读者将#(...)展开为(fn* [p1__9#] ((quote ((first p1__9#) (second p1__9#))))) - 您可以使用(macroexpand-1 '#(...))进行验证。

那里(quote ...)的结果是一个列表,然后您就调用了这个列表,异常就是从这里来的。

(map #([(first %) (second %)]) input)会导致工具发出抱怨。

类似的问题 - #(...)展开为立即尝试将[...]的结果作为无参数的函数调用的东西。

几行之后,使用(map #(vector (first %) (second %)) input)会抛出Execution error (ClassCastException)异常。

将映射视为序列会为您提供一组kv-pair类型的序列,其实现了java.util.Map$Entrykeys函数本应在映射上调用,而不是在任意序列上,虽然它恰好可以与kv-pair的序列一起工作,但它期望每个配对是该Map$Entry接口的一个恰当实例。
通过使用那个(vector ...),您将每个映射条目转换为一个不实现该接口的向量。

一些通用的建议

  • 对于kv-pairs,使用keyval代替firstsecond - 它们也期望一个映射条目,如果出现错误,将更早地失败,使解决问题更容易。它们也更快,更明确地指示代码的意图。
  • 如果您有关于#(...)的问题,尝试将其编写为带有正确命名的参数的(fn [...] ...)(例如,不要使用x而使用kv-pair - 虽然听起来不多,但是如果您遇到困难时有助于解决问题)。
  • 如果您遇到ClassCastException,请仔细阅读您正在调用的函数的文档。
  • 当您看到异常时,研究其堆栈跟踪并尝试找出到底发生了什么。一开始可能很难,但后来在大多数情况下将会变得轻而易举。
...