在Lisp中列出操作

时间:2008-09-05 04:26:50

标签: functional-programming lisp list

我一直在寻找Lisp中的以下功能,并且无处可去:

  1. 查找列表中某些内容的索引。例如:

    (index-of item InThisList)
    
  2. 替换列表中特定位置的内容。例如:

    (replace item InThisList AtThisIndex) ;i think this can be done with 'setf'?
    
  3. 返回特定索引处的项目。例如:

    (return InThisList ItemAtThisIndex)
    
  4. 到目前为止,我一直在假装自己的功能。我想知道我是不是在为自己创造更多的工作。

    这就是我伪造1号的原因:

    (defun my-index (findMe mylist)
      (let ((counter 0) (found 1))
        (dolist (item mylist)
          (cond
            ((eq item findMe) ;this works because 'eq' checks place in memory, 
                      ;and as long as 'findMe' was from the original list, this will work.
             (setq found nil)
            (found (incf counter))))
      counter))
    

6 个答案:

答案 0 :(得分:23)

您可以使用setfnth来按索引替换和检索值。

(let ((myList '(1 2 3 4 5 6)))
     (setf (nth 4 myList) 101); <----
     myList)

(1 2 3 4 101 6)

要按索引查找,您可以使用the position function

(let ((myList '(1 2 3 4 5 6)))
     (setf (nth 4 myList) 101)
     (list myList (position 101 myList)))

((1 2 3 4 101 6) 4)

我发现这些都是in this index of functions

答案 1 :(得分:11)

  
      
  1. 在列表中找到某个内容的索引。
  2.   

在Emacs Lisp和Common Lisp中,你有position函数:

> (setq numbers (list 1 2 3 4))
(1 2 3 4)
> (position 3 numbers)
2

在Scheme中,这是来自DrScheme的doc:

的尾递归实现
(define list-position 
  (lambda (o l)
    (let loop ((i 0) (l l))
      (if (null? l) #f
          (if (eqv? (car l) o) i
              (loop (+ i 1) (cdr l)))))))

----------------------------------------------------

> (define numbers (list 1 2 3 4))
> (list-position 3 numbers)
2
> 

但是如果您使用列表作为存储结构化数据的插槽集合,那么您可能应该查看defstruct甚至某种类似CLOS的Lisp对象系统。

如果您正在学习Lisp,请务必查看Practical Common Lisp和/或The Little Schemer

干杯!

答案 2 :(得分:7)

数目:

  1. (位置项序列&键从头(开始0)结束键测试 - 不)
    http://lispdoc.com/?q=position&search=Basic+search

  2. (setf(elt sequence index)value)

  3. (elt序列索引)
    http://lispdoc.com/?q=elt&search=Basic+search
    注意:elt优于nth,因为elt适用于任何序列,而不仅仅是列表

答案 3 :(得分:4)

杰里米的答案应该有效;但是,如果你发现自己编写了像

这样的代码

(setf(nth i my-list)new-elt)

您可能使用了错误的数据结构。列表只是链表,因此它们是按索引访问的O(N)。你可能最好使用数组。

或者你可能正在使用列表作为元组。在那种情况下,他们应该没事。但是你可能想要命名访问者,所以读取你的代码的人不必记住“nth 4”应该是什么意思。像

这样的东西
(defun my-attr (list)
  (nth 4 list))

(defun (setf my-attr) (new list)
  (setf (nth 4 list) new))

答案 4 :(得分:4)

“实用Common Lisp”的

+2 。它是Common Lisp Cookbook和高质量的自学Lisp书的混合物。

还有“成功的Common Lisp”(http://www.psg.com/~dlamkins/sl/cover.htmlhttp://www.psg.com/~dlamkins/sl/contents.html)似乎填补了“Practical Common Lisp”中的一些空白/扩展内容。

我还阅读了Paul Graham的“ANSI Common Lisp”,它更多地是关于语言的基础知识,但更多的是参考手册。

答案 5 :(得分:0)

我必须同意托马斯的观点。如果你使用像数组这样的列表,那么这将是缓慢的(并且可能很尴尬)。因此,您应该使用数组或坚持使用您编写的函数,但要以某种方式“向上”移动它们,以便以后可以轻松地用数组替换慢速列表。