var可以成为地图中的关键吗?

时间:2014-03-09 20:13:45

标签: map clojure

(def nextStudentNumber 1000)

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

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

2 个答案:

答案 0 :(得分:3)

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

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

由于这对您没有帮助,以下是您的问题的示例构造:

(->> [{: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}]}

请注意,此示例有点多余(因为索引查找可以通过使用索引调用直接在向量中执行)。

但是,它显示了使用不可变数据的基本思想:在独立步骤中,您可以生成ID并进行分组。您可以通过多种方式编写此类步骤,例如为新学生生成ID,将其添加到现有学生的集合中,并按ID对其进行分组。请注意,(group-by :id)步骤的工作方式与ID的生成方式无关,并且可以容忍两个学生具有相同ID的情况,然后您可以检测并处理这些ID。

在功能性Clojure世界中,命令式方法非常不典型。如果您有许多分配学生的功能(并且在您的思考中应该调用s),而是让它们变得纯粹,让他们返回学生的集合,并为他们命名,如load-students-from-filegenerate-ids和使用concatinto之类的结构来组合它们返回的集合,而不需要弄乱状态,直到您使用学生数据进行I / O.

如果出于好奇,你仍然想要处理状态,这里是另一个(相当单一的)代码样本:

(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})))

电子。 G:

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

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

答案 1 :(得分:0)

{:nextStudentNumber {:lastName lastName
                     :firstName firstName
                     :grades {}
                     :id (inc nextStudentNumber)}

我认为你希望这变成像:

{:1000 {:lastName lastName
        :firstName firstName
        :grades {}
        :id (inc nextStudentNumber)}

在这种情况下你会想要:

{(keyword (str nextStudentNumber)) {:lastName lastName
                                    :firstName firstName
                                    :grades {}
                                    :id (inc nextStudentNumber)}

还有一些其他臭臭的东西,如驼峰和inc。我们在clojure中使用悬浮蛇,因此lastName将是last-name。我不知道你在使用inc做了什么,但却发出了强烈的祈祷声。