修改clojure中的嵌套数据

时间:2016-11-10 02:08:05

标签: clojure maps

如何操作嵌套数据结构? 我有这样的清单

[["first_string" {:one 1 :two 2}]
["second_string" {:three 3 :four 4}]
["third_string" {:five 5 :six 6}]
["fourth_string" {:seven 7 :eight 8}]]

我需要将其更改为以下形式:

[["first_string" 1]
["second_string" 3]
["third_string" 5]
["fourth_string" 7]]

基本上,我只希望每个内部向量的第一个元素是地图的第一个键

2 个答案:

答案 0 :(得分:0)

尝试定义一个对向量中的单个条目进行操作的函数,然后map对其进行操作:

(defn manipulate-nested
        [entry]
        [(first entry) (last (first (last entry)))])

(let [input [["first_string" {:one 1 :two 2}]
             ["second_string" {:three 3 :four 4}]
             ["third_string" {:five 5 :six 6}]
             ["fourth_string" {:seven 7 :eight 8}]]]
  (into [] (map manipulate-nested input)))

;; [["first_string" 1] 
;;  ["second_string" 3]   
;;  ["third_string" 5]  
;;  ["fourth_string" 7]]
  

我需要将其更改为此格式

注意:请记住,严格来说,您并非更改(变异)原始向量,而是对其进行修改。

答案 1 :(得分:0)

您无法获得哈希映射的可靠第一个键,因为哈希映射是未排序的数据结构,因此它们没有顺序保证。所以没有第一个或第二个。

没有办法对关键字:one:two:three进行数字排序,而无需解析我将其留下的名称作为单独的问题。

以下是用有序结构代替哈希映射的问题:

(def data [["first_string" [[:one 1] [:two 2]]]
           ["second_string" [[:three 3] [:four 4]]]
           ["third_string" [[:five 5] [:six 6]]]
           ["fourth_string" [[:seven 7] [:eight 8]]]]

一个典型的惯用解决方案是从data中的每个向量独立地通过map提取,在转换函数绑定向量中使用destructuring来绑定所需的嵌套元素并返回此提取在一个新的载体中:

(map (fn [[s [[_ n] _]]] [s n]) data)

通过重用传递的向量而不是在每个步骤中构建一个新向量,特定问题的输入数据结构提供了一种减少开销的方法:

(map #(update % 1 (comp second first)) data)