`
iyuan
  • 浏览: 469878 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

lisp初体验-Practical Common Lisp笔记-4.迷你数据库-中

    博客分类:
  • lisp
阅读更多
额,先简单申明下,由于本站code不支持lisp,而原先的代码着实不利于排版(太丑了),这里凡是代码部分都用python的格式,凡是输出部分都用java的格式~

作为一个数据库,纵然再mini,也得要有最基本的功能:增删改查,本篇就逐一加上。


作为lisp代码,如果查找能类似这样:
(select :artist "Dixie Chicks")

还是蛮不错的。自然,万能的宏已经准备好了类似的动作:REMOVE-IF-NOT,遍历列表,如果不符合要求则删除(不要担心,这里只是个副本,不会影响原数据),显示出的自然就是咱要的东西了。
试试看:
代码:
(remove-if-not #'evenp '(1 2 3 4 5 6 7 8 9 10))

结果:
(2 4 6 8 10)

evenp也是宏,用于取偶,这里还有个有趣的东东:#'符号,用来表明,后面是个函数,不是变量哦(注意是#和'两个符号组合,后面还有一个单引号',那是和后面的列表一起的,表示那是个列表)。
上面的代码还有另一种写法:
 (remove-if-not #'(lambda (x) (= 0 (mod x 2))) '(1 2 3 4 5 6 7 8 9 10))

这里用了匿名函数:
(lambda (x) (= 0 (mod x 2)))

加上用于比对字符串的默认函数:equal,便得到了搜索语句:
(remove-if-not
  #'(lambda (cd) (equal (getf cd :artist) "Dixie Chicks")) *db*)

封装下:
(defun select-by-artist (artist)
  (remove-if-not
   #'(lambda (cd) (equal (getf cd :artist) artist))
   *db*))

这里用到的匿名函数似乎有局限,总不能每一个字段都写一套吧,那么这样呢:
(defun select (selector-fn)
  (remove-if-not selector-fn *db*))

然后:
(select #'(lambda (cd) (equal (getf cd :artist) "Dixie Chicks")))

你没有看错,这里将匿名函数作为参数来传递,当然普通函数也可以这样做:
(defun artist-selector (artist)
  #'(lambda (cd) (equal (getf cd :artist) artist)))
(select (artist-selector "Dixie Chicks"))

哪种比较好就见仁见智了。不过,似乎还是比较麻烦,整体上就字段有差异,不至于要写这么多重复的东西吧,让咱先跳出这个问题,看看这个:
(defun foo (a b c) (list a b c))
(defun foo (&key a b c) (list a b c))

两者的区别在于第一个必须参数全部输入,而第二个则不。
例如:
(foo :a 1 :c 3) ==> (1 NIL 3)

既然允许这么传参,那么自然也就允许默认值了:
(defun foo (&key a (b 20) (c 30 c-p)) (list a b c c-p))

注意:这里的c-p是用来确认c是否是有传入值,有则为t(真),标准格式:x-p
测试:
(foo :a 1 :b 2 :c 3)  ==> (1 2 3 T)
(foo :c 3 :b 2 :a 1)  ==> (1 2 3 T)
(foo :a 1 :c 3)       ==> (1 20 3 T)
(foo)                 ==> (NIL 20 30 NIL)

如此,最终的查询语句应该是这个样子:
(select (where :artist "Dixie Chicks"))

where函数:
(defun where (&key title artist rating (ripped nil ripped-p))
  #'(lambda (cd)
      (and
       (if title    (equal (getf cd :title)  title)  t)
       (if artist   (equal (getf cd :artist) artist) t)
       (if rating   (equal (getf cd :rating) rating) t)
       (if ripped-p (equal (getf cd :ripped) ripped) t))))

至此,查询功能算完结了。


理论上来说,完成了where函数后,更新操作应该不难:
(defun update (selector-fn &key title artist rating (ripped nil ripped-p))
  (setf *db*
        (mapcar
         #'(lambda (row)
             (when (funcall selector-fn row)
               (if title    (setf (getf row :title) title))
               (if artist   (setf (getf row :artist) artist))
               (if rating   (setf (getf row :rating) rating))
               (if ripped-p (setf (getf row :ripped) ripped)))
             row) *db*)))

这里主要用到默认宏:mapcar,用于遍历db,funcall没有给出说明。这条算目前为止逻辑最复杂的函数了。主体是遍历出所有数据,有更新的换成新数据,然后重新覆盖原来的db(作为一个数据库,动作有点大)。
用法:
(update (where :artist "Dixie Chicks") :rating 11)



相比改,删除似乎更加容易:
(defun delete-rows (selector-fn)
  (setf *db* (remove-if selector-fn *db*)))

至此,似乎全部ok了,且慢,难道不觉得有些缺憾么?

(未完待续)
0
1
分享到:
评论

相关推荐

    Practical Common Lisp-1st-2005

    《Practical Common Lisp-1st-2005》是一本专注于Common Lisp编程语言的实用书籍,作者Peter Seibel通过这本书向读者展示了如何使用Common Lisp来解决真实世界中的问题,强调程序员作为工程师和艺术家的双重身份,而...

    common-lisp-the-language-second-edition.PDF

    common-lisp-the-language-second-edition.PDF

    Practical Common Lisp笔记

    《Practical Common Lisp笔记》是一本深入探讨Common Lisp编程语言的实用教程。Common Lisp是一种功能强大的多范式编程语言,以其动态类型、宏系统和丰富的内置数据结构而闻名。这篇笔记详细记录了作者在学习过程中...

    cad-lisp-3-表操作.LSP.lsp

    cad-lisp-3-表操作.LSP.lsp

    Lisp - 1990 - Common Lisp the Language, 2nd Edition - Steele, Guy L..pdf

    《Common Lisp the Language, 2nd Edition》是Guy L. Steele所著的一本关于Common Lisp编程语言的权威指南,作为第二版,它不仅继承了前一版的经典,还对Lisp语言进行了深入的扩展和更新。这本书是Lisp爱好者的宝贵...

    emacs-lisp-intro-2.04.tar.gz

    标题中的"emacs-lisp-intro-2.04.tar.gz"是一个典型的压缩文件名,它表明这个文件是一个关于Emacs Lisp的介绍性资料,并且版本号是2.04,格式为tar.gz。tar.gz是一种在Linux和Unix系统中常用的文件压缩格式,它先用...

    实用Common.Lisp编程.pdf

    Common Lisp中的Common Lisp Object System (CLOS)提供了多重继承和多态性的支持,使得面向对象编程在Common Lisp中成为可能。 #### 5. 跨平台性 Common Lisp编写的程序可以在多种操作系统上运行,包括Windows、...

    Practical Common Lisp pdf

    在压缩文件中,只有一个名为"practical_common_lisp.pdf"的文件,这是本书的PDF版本。由于原版PDF文件较大,经过7z压缩后,文件大小显著减小,便于下载和存储,但同时也能保持较好的图像和文字质量,满足读者的阅读...

    Successful Lisp How to Understand and Use Common Lisp - David B. Lamkins

    Provides practical advice for the construction of Common Lisp programs. Shows examples of how Common Lisp is best used. Illustrates and compares features of the most popular Common Lisp systems on ...

    ANSI Common Lisp 中文翻译版.pdf

    4. Common Lisp 对象系统是一种强大的对象系统,广泛应用于实际开发中。 5. 速度、进阶议题和推论是 Lisp 语言的高级主题。 6. 生成 HTML、对象和调试是 Lisp 语言的实践主题。 7. ANSI Common Lisp 语言广泛应用于...

    AutoLisp源文件--标注高程.LSP

    AutoLisp源文件--标注高程.LSP

    practical common lisp.pdf

    1. **数据库开发**:Common Lisp可以通过多种方式与数据库交互,如使用SQL或特定的Lisp库来操作数据。 2. **单元测试框架**:书中介绍了一种用于编写测试用例的方法,并且展示了如何使用Common Lisp构建一个完整的...

    实用Common.Lisp编程

    这本《Practical Common Lisp》之所以号称Practical,正是因为这本书大量介绍Common Lisp在现实世界中的各种应用方式,算是第一本「入世传教」的Common Lisp著作。《Practical Common Lisp》是目前最畅销的Common ...

    CommonLisp数据库

    CommonLisp 的简单而复杂的MP3 数据库,根据实用CommonLisp编程

    Practical Common Lisp

    Practical Common Lisp 学习lisp的入门书籍

    Lisp-music-player.rar_autolisp_autolisp程序_lisp_player

    标题中的“Lisp-music-player.rar”表明这是一个基于Lisp语言开发的音乐播放器软件,其源代码或可执行文件被压缩在RAR格式的文件中。RAR是一种流行的压缩格式,通常用于存储和分发多个文件,它允许用户将多个文件...

    lisp小工具-fx.zip

    计算多个数字之和、计算多条线段长度之和、插入墙高标注、查询多段线顶点坐标并绘制、自动生成页码、绘制示坡线、插入排水箭头 https://blog.csdn.net/qq_24141055/article/details/121446354

    Common-Lisp-Actors, 通用Lisp的actor系统.zip

    Common-Lisp-Actors, 通用Lisp的actor系统 这是一个简单且易于使用的Actor系统,在。设置需要波尔多螺纹。http://common-lisp.net/project/bordeaux-threads/ 2. 加载 actors.lisp 并开始使用它。 如果你有 Quick

    lisp解密程序-适用于早期的Lisp程序

    Lisp是一种古老而强大的编程语言,它以其独特的语法和哲学在计算机科学领域中占有一席之地。Lisp的全称是“List Processing”,意为列表处理,它的核心思想是使用S表达式(一种类似括号包围的数据结构)来表示代码和...

Global site tag (gtag.js) - Google Analytics