Clojure函数不返回映射
我不熟悉Clojure和函数式编程。我对Clojure中的数据结构有一个基本的了解,比如地图、列表和向量 我正在尝试编写一个返回嵌套映射的函数。地图在功能内正确显示。以下代码来自Clojure函数不返回映射,clojure,functional-programming,Clojure,Functional Programming,我不熟悉Clojure和函数式编程。我对Clojure中的数据结构有一个基本的了解,比如地图、列表和向量 我正在尝试编写一个返回嵌套映射的函数。地图在功能内正确显示。以下代码来自读取客户文件功能 ([input-list new-map place-holder] (if (not-empty input-list) (do (def string-input (str (first input-list)))
读取客户文件
功能
([input-list new-map place-holder]
(if (not-empty input-list)
(do
(def string-input (str (first input-list)))
(def cust-id (get (first input-list) 0))
(def cust-name (get (first input-list) 1))
(def cust-address (get (first input-list) 2))
(def cust-phone (get (first input-list) 3))
(def temp-map (conj new-map {(keyword cust-id) {:cust-name cust-name, :cust-address cust-address, :cust-phone cust-phone}}))
(read-customer-file (rest input-list) temp-map ())
)
(do
(map str new-map)
;(print (get-in new-map [:1 :cust-name]))
(print new-map)
)
)
)
这需要输入向量列表,如下所示:
([3 Fan Yuhong 165 Happy Lane 345-4533] [2 Sue Jones 43 Rose Court Street 345-7867] [1 John Smith 123 Here Street 456-4567])
{:3 {:cust-name Fan Yuhong, :cust-address 165 Happy Lane, :cust-phone 345-4533}, :2 {:cust-name Sue Jones, :cust-address 43 Rose Court Street, :cust-phone 345-7867}, :1 {:cust-name John Smith, :cust-address 123 Here Street, :cust-phone 456-4567}}
并返回嵌套映射,如下所示:
([3 Fan Yuhong 165 Happy Lane 345-4533] [2 Sue Jones 43 Rose Court Street 345-7867] [1 John Smith 123 Here Street 456-4567])
{:3 {:cust-name Fan Yuhong, :cust-address 165 Happy Lane, :cust-phone 345-4533}, :2 {:cust-name Sue Jones, :cust-address 43 Rose Court Street, :cust-phone 345-7867}, :1 {:cust-name John Smith, :cust-address 123 Here Street, :cust-phone 456-4567}}
这就是我试图实现的目标,并且在函数中工作得非常好。但是,如果我试图用返回类型的值定义函数外部的变量,我不会得到嵌套映射,而是字符串列表。为此,我只需删除(打印新地图)
部分
(do
(map str new-map)
)
并从函数定义外部调用它,如下所示:
(def customer-info-list read-customer-file)
(println (customer-info-list))
我得到的结果与我预期的不同,无法执行与地图相关的功能,例如get
和get in
([:3 {:cust-name Fan Yuhong, :cust-address 165 Happy Lane, :cust-phone 345-4533}] [:2 {:cust-name Sue Jones, :cust-address 43 Rose Court Street, :cust-phone 345-7867}] [:1 {:cust-name John Smith, :cust-address 123 Here Street, :cust-phone 456-4567}])
我将非常感谢在这方面的任何帮助。我知道我的代码有点乱,我应该使用let
而不是def
作为变量名。但我刚刚开始Clojure,这是我的第一个项目
更新
我解决了这个问题。我所做的是在函数内部将映射更改为排序映射。因此,函数的最后一次返回将是一个排序映射
(do
(into (sorted-map) new-map)
)
但是,如果分配给变量,返回值仍然是字符串,因此我再次将其转换为排序映射。然后它最终被转换成一个嵌套的映射
(def customer-info-list read-customer-file)
(def cust-map (into (sorted-map) (customer-info-list)))
(println cust-map)
(println (get-in cust-map [:1 :cust-name]))
(println (get cust-map :2))
上述三条打印语句的输出与预期一致
{:1 {:cust-name John Smith, :cust-address 123 Here Street, :cust-phone 456-4567}, :2 {:cust-name Sue Jones, :cust-address 43 Rose Court Street, :cust-phone 345-7867}, :3 {:cust-name Fan Yuhong, :cust-address 165 Happy Lane, :cust-phone 345-4533}}
John Smith
{:cust-name Sue Jones, :cust-address 43 Rose Court Street, :cust-phone 345-7867}
我能够通过在返回时将其转换为排序地图来解决问题。此外,返回的值再次被转换为一个排序映射,从而实现了这一目的。请查看更新部分。我可以通过在返回时将其转换为排序地图来解决问题。此外,返回的值再次被转换为一个排序映射,从而实现了这一目的。请查看更新部分。您的代码中有许多错误,与缺乏基本clojure知识有关: 1) 不要在函数内部使用
def/defn
,而是使用let
2) 通常使用assoc
3) 最好从函数中返回一些有意义的值,并在外部对其进行反思
我将以更为简洁的方式重写您的函数,如下所示:
(我打算保留占位符
参数,尽管它没有在代码中的任何地方使用,所以我无法推断它的用途)
答复:
user> (read-customer-file [["a" "b" "c" "d"] ["e" "f" "g" "h"]] {} ())
;;=> {:a {:cust-name "b", :cust-address "c", :cust-phone "d"},
;; :e {:cust-name "f", :cust-address "g", :cust-phone "h"}}
但您真正需要的是一些更高阶的数据处理功能,如map
:
(defn read-customer-file [input-list placeholder]
(into {}
(map (fn [[id name address phone]]
[(keyword id) {:cust-name name
:cust-phone phone
:cust-address address}])
input-list)))
user> (read-customer-file [["a" "b" "c" "d"] ["e" "f" "g" "h"]] {})
;;=> {:a {:cust-name "b", :cust-phone "d", :cust-address "c"},
;; :e {:cust-name "f", :cust-phone "h", :cust-address "g"}}
或减少:
(defn read-customer-file [input-list placeholder]
(reduce (fn [res [id name address phone]]
(assoc res (keyword id) {:cust-name name
:cust-phone phone
:cust-address address}))
{} input-list))
此外,最好将业务逻辑(在您的案例文件记录到客户转换中)抽象为一些专门的功能,以使处理功能更通用:
(defn file-rec->customer [[id name address phone]]
[(keyword id) {:cust-name name
:cust-address address
:cust-phone phone}])
(defn read-data-file [record-processor input-list placeholder]
(into {} (map record-processor) input-list))
user> (read-data-file file-rec->customer [["a" "b" "c" "d"] ["e" "f" "g" "h"]] {})
;;=> {:a {:cust-name "b", :cust-address "c", :cust-phone "d"},
;; :e {:cust-name "f", :cust-address "g", :cust-phone "h"}}
您的代码中有许多错误,与缺乏基本clojure知识有关:
1) 不要在函数内部使用def/defn
,而是使用let
2) 通常使用assoc
3) 最好从函数中返回一些有意义的值,并在外部对其进行反思
我将以更为简洁的方式重写您的函数,如下所示:
(我打算保留占位符
参数,尽管它没有在代码中的任何地方使用,所以我无法推断它的用途)
答复:
user> (read-customer-file [["a" "b" "c" "d"] ["e" "f" "g" "h"]] {} ())
;;=> {:a {:cust-name "b", :cust-address "c", :cust-phone "d"},
;; :e {:cust-name "f", :cust-address "g", :cust-phone "h"}}
但您真正需要的是一些更高阶的数据处理功能,如map
:
(defn read-customer-file [input-list placeholder]
(into {}
(map (fn [[id name address phone]]
[(keyword id) {:cust-name name
:cust-phone phone
:cust-address address}])
input-list)))
user> (read-customer-file [["a" "b" "c" "d"] ["e" "f" "g" "h"]] {})
;;=> {:a {:cust-name "b", :cust-phone "d", :cust-address "c"},
;; :e {:cust-name "f", :cust-phone "h", :cust-address "g"}}
或减少:
(defn read-customer-file [input-list placeholder]
(reduce (fn [res [id name address phone]]
(assoc res (keyword id) {:cust-name name
:cust-phone phone
:cust-address address}))
{} input-list))
此外,最好将业务逻辑(在您的案例文件记录到客户转换中)抽象为一些专门的功能,以使处理功能更通用:
(defn file-rec->customer [[id name address phone]]
[(keyword id) {:cust-name name
:cust-address address
:cust-phone phone}])
(defn read-data-file [record-processor input-list placeholder]
(into {} (map record-processor) input-list))
user> (read-data-file file-rec->customer [["a" "b" "c" "d"] ["e" "f" "g" "h"]] {})
;;=> {:a {:cust-name "b", :cust-address "c", :cust-phone "d"},
;; :e {:cust-name "f", :cust-address "g", :cust-phone "h"}}
def
-在函数中进行加密通常是您不想做的事情。使用let
。def
-ing在函数中通常是您不想做的事情。使用让
代替。感谢您提供如此详细的答案。我可以看出我的函数式编程技能是缺乏的,因为我是这个范例的新手。谢谢你提供了如此详细的答案。我可以看出,我的函数编程技能是缺乏的,因为我是这个范例的新手。