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

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 知识汇总: 实现一个索引函数

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

这个函数必须:

  1. 可以接受任意组合类型
  2. 顺序集合返回数字索引,对mapset返回key
  3. 否则返回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种数据结构上操作。作为这些情况的必然后果,金字塔矗立在那里千年不变,而有机体则必须演化,否则就会死亡。”

而在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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值