var可以是地图中的键吗? [英] Can a var be a key in a map?

查看:188
本文介绍了var可以是地图中的键吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 (def nextStudentNumber 1000)

(defname s
[lastName firstName]
(let [student {:nextStudentNumber {:lastName lastName
:firstName firstName
:grades {}
:id(inc nextStudentNumber)}}]

在这个例子中,我创建了var nextStudentNumber ,并且我想要映射那些在学生上改变的键。

解决方案

是的,像任何对象一样var可以是一个地图中的键:

  {#'foo 42} 
=> {#'user / foo 42}

由于这不会帮助你,这里是一个你的问题的示例结构:

 ( - >> [{:nameMara} {:nameLara} {:nameClara}] 
(map-indexed#(assoc%2:id%1)) ;;为每个学生分配一个ID
(group-by:id));;创建哈希映射,学生可以通过ID
=> {0 [{:nameMara,:id 0}],1 [{:nameLara,:id 1}]
2 [{:nameClara,:id 2}]}

请注意,此示例有点冗余(因为索引查找可以直接通过调用向量



然而,它显示了使用不可变数据的基本想法:在独立的步骤中,您生成ID并进行分组,您可以以多种方式组成这些步骤请注意,(group-by:id)步骤独立于如何工作生成ID并允许两个学生具有相同ID然后可以检测和处理的情况。



命令式方法在函数Clojure世界中非常不典型,如果你有很多函数分配学生(在你的思想中应该调用 s ),而不是使它们是纯的,让他们返回学生的集合,并给他们名字如 load-students-from-file generate-ids 并使用 concat into 以组合它们返回的集合,而不需要混乱状态,直到您对学生数据执行I / O操作。



如果,出于好奇,你仍然想要搞乱状态,这里是另一个(而不是unidiomatic)代码示例:

 (def student-count(atom 0))
(def students-by-id(atom {}))

defn add-student![first-name last-name]
(let [next-id(swap!student-count inc)]
(swap!students-by-id
assoc next -id {:first-name first-name,:last-name last-name
:id next-id})))

E。 g。:

 (add-student!MaraMad)
(add-student! Light)
(@ students-by-id 1)
=> {:first-nameLara,:last-nameLight,:id 1}

正如你所看到的,一切都在这里一步一步。


(def nextStudentNumber 1000)

(defn s
  [lastName firstName]
  (let [student {:nextStudentNumber {:lastName lastName
                                     :firstName firstName
                                     :grades {}
                                     :id (inc nextStudentNumber)}}]

In this instance, I have created the var nextStudentNumber and I want to have map that keys that change on the of the student.

解决方案

Yes, like any object a var can be a key in a map:

{#'foo 42}
=> {#'user/foo 42}

Since that won't help you, here is an example construct for your question:

(->> [{:name "Mara"} {:name "Lara"} {:name "Clara"}]
     (map-indexed #(assoc %2 :id %1)) ;; assign an ID to each student
     (group-by :id)) ;; Create a hash-map where students can be looked up by ID
=> {0 [{:name "Mara, :id 0}], 1 [{:name "Lara", :id 1}]
    2 [{:name "Clara", :id 2}]}

Notice that this example is a bit redundant (as index lookup can be performed in a vector directly by invoking it with the index).

However, it shows the basic idea of working with immutable data: In independent steps you generate IDs and do grouping. You can compose such steps in many ways, like generating IDs for new students, adding them to a collection of existing students and grouping them by ID. Notice that the (group-by :id) step works independently of how the IDs are generated and tolerates scenarios where two students have the same ID which you can then detect and handle.

The imperative approach is very untypical in functional Clojure world. If you have many functions that allocate students (and in your thinking should invoke s), rather make them pure and let them return collections of students and give them names like load-students-from-file, generate-ids and use constructs like concat, into to combine collections returned by them without the need to mess with state, until you do I/O with the student data.

If, out of curiosity, you still want to mess with state, here is another (rather unidiomatic) code-sample:

(def student-count (atom 0))
(def students-by-id (atom {}))

(defn add-student! [first-name last-name]
   (let [next-id (swap! student-count inc)]
     (swap! students-by-id
            assoc next-id {:first-name first-name, :last-name last-name
                           :id next-id})))

E. g.:

(add-student! "Mara" "Mad")
(add-student! "Lara" "Light")
(@students-by-id 1)
=> {:first-name "Lara", :last-name "Light", :id 1}

As you can see, everything is complected in one step here.

这篇关于var可以是地图中的键吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆