gpt4 book ai didi

dictionary - doseq 中的 assoc 字符串导致空映射

转载 作者:行者123 更新时间:2023-12-02 01:20:32 25 4
gpt4 key购买 nike

我正在通过解决问题来学习 Clojure,我陷入困境 with one of them ,基本上我必须在日志文件中找到前五个字符串。

这是我到目前为止所得到的:

(ns topfive
(:import (java.io BufferedReader FileReader)))


(defn extract-query [line]
(.substring line (+ (.lastIndexOf line "=") 1) (.lastIndexOf line "]")))

(defn process-file [file-name, queries]
(with-open [rdr (BufferedReader. (FileReader. file-name))]
(doseq [line (line-seq rdr)]
(assoc queries (extract-query line) (inc (get queries (extract-query line) 0))))))

(process-file "in" {})

我的问题是 queries 不包含任何内容,我已经检查过 extract-queries 返回我想要的字符串,我认为这可能有问题与语言本身有关,I've read Clojure 在语言级别具有不变性,但这对我来说仍然不是一个好点。

你能对我做错的事情提出一些建议吗?

最佳答案

Clojure 确实具有低级别的不变性,并且 HashMap 是不可变的。因此,assoc 不会就地改变映射,它会创建一个包含更新项的新映射,并返回新映射。您一遍又一遍地调用 assoc,但丢弃结果。

一个修复方法是使用 reduce 而不是 doseqdoseq 迭代 seq 并对每个项目执行某些操作,但不会累积任何结果。所以它应该主要用于有副作用的事情,例如打印到屏幕或文件。 reduce 类似地迭代 seq,但它确实会累积结果。

(defn process-file [file-name, queries]
(with-open [rdr (BufferedReader. (FileReader. file-name))]
(reduce (fn [queries, line]
(assoc queries (extract-query line) (inc (get queries (extract-query line) 0))))
queries
(line-seq rdr))))

您可以做一些事情来进一步简化这一点。 process-file 不需要 queries 参数,因为它一开始总是一个空映射。使用 update-infnil 可以更简洁地编写 assoc 行;这也让我们避免每行调用两次 extract-query 。您可以使用 clojure.java.io 中的 Clojure 包装器 reader 替换对 Java Reader 类的所有调用。您可以用正则表达式替换对 substring 的调用;正则表达式更简洁,但对于大量输入,您的版本可能执行得更快。您还可以使用 #() 将示例中的匿名函数替换为含糖阅读器宏版本,尽管此时它开始看起来有点吵,所以我可能会使用 let 使其读起来更好一点。

(ns topfive
(:require [clojure.java [io :as io]]))

(defn extract-query [line]
(nth (re-find #"query=([^]]+)" line) 1))

(defn process-file [file-name]
(with-open [rdr (io/reader file-name)]
(reduce #(let [search-term (extract-query %2)]
(update-in %1 [search-term] (fnil inc 0)))
{}
(line-seq rdr))))

关于dictionary - doseq 中的 assoc 字符串导致空映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6418177/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com