clojure解构(clojure destructuring)

【转】http://rritw.com/a/JAVAbiancheng/JAVAzonghe/20130615/370731.html

由于在clojure中如果只靠一些集合到操作函数如first、last、nth等函数,不能够简洁的获取一些嵌套集合中的元素,所以需要destructuring来使我们可以简洁快速的去获取集合中的元素。

由于在clojure中如果只靠一些集合到操作函数如first、last、nth等函数,不能够简洁的获取一些嵌套集合中的元素,所以需要destructuring来使我们可以简洁快速的去获取集合中的元素。 clojure支持的结构有:有顺序集合(sequential collection)的解构和map的解构。

 一、Sequential destructuring 有序集合包括:clojure的list,vector以及sequence。所有实现java.util.List接口的集合:java数组、字符串 

1、根据位置对应来解构

(def v [42 "foo" 99.2 [5 12]])
(let [[xyz] v]
  (+ xz))
;= 141.2

;;使用下划线占位
(let [[x _ _ [yz]] v] 
  (+ xyz))
;= 59

2、收集剩余的元素(Gathering extra-positional sequential values​​) 
;;使用&来收集
(let [[x & rest] v] 
  rest)
;= ("foo" 99.2 [5 12])

3、保留解构的值(retaining the destructured value) 
;;使用as来保留解构的值
(let [[x _ z :as original-vector] v] 
  (conj original-vector (+ xz)))
;= [42 "foo" 99.2 [5 12] 141.2]


二、Map destructuring 可以进行map解构的类型有:   clojure hash-map,array-map,record。   所有实现java.util.Map接口的集合   支持get函数获取相应值的对象,如:clojure vector,string,array1、位置对应来解构 

(def m {:a 5 :b 6 
        :c [7 8 9] 
        :d {:e 10 :f 11}
        "foo" 88
        42 false})
;;注意:这里key不单是:key类型,也可以是其他类型
(let [{a :ab :b} m] 
  (+ ab))
;= 11

;;注意:如果是数组、字符串或vector,解构的key是下标
(let [{x 3 y 8} [12 0 0 -18 44 6 0 0 1]] 
  (+ xy))
;= -17

;;顺序解构和map解构混合
(let [{[x _ y] :c} m] 
  (+ xy))
;= 16

(def map-in-vector ["James" {:birthday (java.util.Date. 73 1 6)}])
;= #'user/map-in-vector

(let [[name {bd :birthday}] map-in-vector]
  (str name " was born on " bd))
;= "James was born on Thu Feb 06 00:00:00 EST 1973"

2、保留解构的值(retaining the destructured value) 
和顺序解构一样用as来保存。 
(let [{r1 :x r2 :y :as randoms}
       (zipmap [:x :y :z] (repeatedly (partial rand-int 10)))]
(assoc randoms :sum (+ r1 r2)))
;= {:sum 17, :z 3, :y 8, :x 9}

3、默认值(Default values​​) 
(let [k :unkown x :a 
       :or {k 50}
       m]
  (+ kx))
;;= 55     

4、绑定值到对应的key上(binding values​​ to their key's name) 
;;这里的可以用:keys、:strs、:syms来指定key的类型
;;但是通常使用:keys类型
;;在很多框架中,经常会看到:keys,:or,:as的组合使用
(def chas {:name "Chas" :age 31 :location "Massachusetts"}) 
(let [{name :name age :age location :location} chas]
  (format "%s is %s years old and lives in %s." name age location)) 
;= "Chas is 31 years old and lives in M​​assachusetts."

5、对剩余部分像map一样解构(Destructuring rest sequences as map key/value pairs) 
;;这个代码太乱,有洁癖的人受不鸟
(def user-info ["robert8990" 2011 :name "Bob" :city "Boston"])
(let [[username account-year & extra-info] user-info
       {:keys [name city]} (apply hash-map extra-info)] 
  (format "%s is in %s" name city))
;= "Bob is in Boston"

;;如果剩余部分的参数个数是偶数个的话,可以用map解构
;;有洁癖的人现在觉得世界清静多了
(let [[username account-year & {:keys [name city]}] user-info] 
  (format "%s is in %s" name city))
;= "Bob is in Boston"


最后,虽然以上的例子只是用let,但是解构用在fn、defn等地方都是可以的。  
    

参考文档:《clojure programming》 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值