您的位置:首页 > 其它

Clojure练习-5.组合数据类型

2015-05-30 20:36 387 查看

Clojure练习-5.组合数据类型

5. 组合数据类型

“用100个函数来操作一个数据结构比10个函数操作10个数据结构要好很多。基于一个统一的数据结构,我们可以构建出一系列的小函数,这些小函数又可以组合起来形成一个强大的系统。而为不同的数据结构编写不同的函数,在根本上就削减了复用的可能。” —— [ Alan Perlis ]

5.2 vector: 创建和使用vector的各种变体

实现一个函数:已知 一个二维方阵,

输入: 某点位置

返回: 某点的所有邻接位置(不包括对角线方向)。

(defn neighbors
  "在二维方阵中查找某点邻接位置
  输入:
   size 表示 二位方阵的边长
   xy   表示 某点
   Δ    表示 相对于xy的距离
  返回: 如 ((1 0) (0 1))
  "
  ([size xy] (neighbors [[-1 0] [1 0] [0 -1] [0 1]] size xy))
  ([Δ size xy]
   (filter (fn [an-xy] (every? #(< -1 % size) an-xy)) ;filter的实参1
           (map #(map +  [0 0] %) Δ) ;filter的实参2 
    )
   )
  )


测试

;;测试
(def matrix
  "二维方阵"
  [[1 2 3] [4 5 6] [7 8 9]])

(neighbors 3 [0 0]);=> ((1 0) (0 1))
(map #(get-in matrix %) (neighbors 3 [0 0])); => (4 2)


5.7 知识汇总: 实现一个索引函数

实现一个函数,在一个序列里定位某个元素的位置索引。

这个函数必须:

可以接受任意组合类型

顺序集合返回数字索引,对mapset返回key

否则返回nil

解1

(defn index-of-coll 
   "索引函数
    输入: coll,某个元素e  (coll代表集合类型:顺序类型 set或者map) (e是用来匹配的项)
    返回:索引号   (特殊的map返回key)
  "
  {:added "1.0"}
  [coll e]
  (let [cmp (if (map? coll) #(= (second %1) %2) #(= %1 %2)) ] ;; 定义比较表达式
    ;; 遍历比较
    (loop [s coll, idx 0] ;; 开始循环
      (when (seq s) ;; 退出条件 
        (if (cmp (first s) e) ;; 如果相等  
             (if (map? coll) ;; 如果是map
               (first (first s))  ;; 返回key
               idx) ;; 否则返回索引
             (recur (next s) (inc idx))))))) ;; 跳转到循环


测试

(def a-to-z (map char (range 97 123)))

(index-of-coll a-to-z \z) ;=> 25
(index-of-coll (set a-to-z) \z) ;=>25

(def A-to-Z (map char (range 65 91)))
(def my-map (zipmap A-to-Z a-to-z))

(index-of-coll my-map \z) ;=> \Z


解2

(defn index-of-coll' 
  {:added "终极版"}
  [coll] (cond (map? coll) (seq coll) (set? coll) (map vector coll coll) :else (map vector (iterate inc 0) coll) ))


(defn pos 
     "索引函数
    输入: coll,某个元素e  (coll代表集合类型:顺序类型 set或者map) (e是用来匹配的项)
    返回:索引号   (特殊的map返回key)
  "
  {:added "终极版"}
  [coll ele]
  (for [[i e] (index-of-coll' coll ) :when (= e ele)]  i))


测试

(pos A-to-Z \Z) ;=> (25)
(pos (set a-to-z) \z) ;=> (\z)
(pos my-map \z) ;=> (\Z)


其他

而在Pascal里,数据结构的过度声明导致函数的专用性,阻碍并惩罚临时性的合作,(在Pascal中)采用100个函数在一种数据结构上操作,远远优于用10个函数在10种数据结构上操作。作为这些情况的必然后果,金字塔矗立在那里千年不变,而有机体则必须演化,否则就会死亡。”



[1]: SICP读书笔记(2)——扉页,序 - - ITeye技术网站

http://kidneyball.iteye.com/blog/923957

[2]:Fun with underscore.js - GitBook

https://www.gitbook.com/book/juntao/fun-with-underscore/details

[3]: Clojure 学习入门(12)—— map/pmap - IT-Homer - 博客频道 - CSDN.NET

http://blog.csdn.net/ithomer/article/details/17591499
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: