如何将嵌套向量转换为向量映射?

时间:2018-01-15 22:57:10

标签: clojure

鉴于我有以下形式:

(def data-points [[1483249740 "ONE"]
                  [1483249680 "TWO"]
                  [1483249620 "THREE"]
                  [1483249560 "FOUR"]])

如何将此数据转换为此数据?

{:data  [1483249740 1483249680 1483249620 1483249560] 
 :value ["ONE" "TWO" "THREE" "FOUR"]}

我也想知道如何处理类似的问题。 你有什么方法可以解决这个问题,以及我需要知道哪些函数来转换任何数据。

我是clojure的新手,并且找不到令人满意的解决方案。
谢谢

4 个答案:

答案 0 :(得分:7)

我会用这个:

(zipmap [:data :value] (apply map vector data-points))

;;=> {:data [1483249740 1483249680 1483249620 1483249560], 
;;    :value ["ONE" "TWO" "THREE" "FOUR"]}

它对数据集合使用单次传递,但比减少更简洁,但在性能方面不应该有所不同

代码段(apply map vector data)是一种在clojure中转置矩阵的惯用方法(在您的情况下,它是您需要的,因为它将列转换为行)

user> (apply map vector [[:a 1] [:b 2] [:c 3]])
;;=> ([:a :b :c] [1 2 3])

答案 1 :(得分:1)

我可能会把它写成减少。这种方法只需要对“数据点”进行一次传递,这可能是更好的选择。

(reduce
  (fn [m [data value]]
    (-> m
        (update :data conj data)
        (update :values conj value)))
  {:data [] :values []}
  data-points)

答案 2 :(得分:0)

另一种既有效又易于使用的表示形式:

(def data-points-map
  (into {} data-points))

然后你可以做

(get data-points-map 1483249740)

获得“ONE”。否则你需要

(aget (:value m) (.indexOf (:data m) 1483249740))

获得相同的结果。

最后你可以

{:data (keys data-points-map)
 :value (values data-points-map)}

在原始问题中获得“怪异”的表示。

答案 3 :(得分:0)

这是一种功能强大的方法

function getUserTimeZoneDateTime() {

    var currentUtcDateTime = moment.utc().toDate();
    var mod_start = new Date(currentUtcDateTime.setMinutes(GlobalValues.OffsetMinutesFromUTC - currentUtcDateTime.getTimezoneOffset()));
    var currentUserDateTime= moment(mod_start).format('MM/DD/YYYY h:mm A');

    return currentUserDateTime;
};

作为一项功能:

(->> data-points
     (mapv (partial mapv vector))
     (mapv (partial zipmap [:data :value]))
     (reduce (partial merge-with into)))

(我不建议实际使用其中任何一种,只是为了好玩而提出这个)