7

我一直在到处寻找 Lisp 中的以下功能,但一无所获:

  1. 在列表中找到某物的索引。例子:

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

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

    (return InThisList ItemAtThisIndex)
    

到目前为止,我一直在用我自己的函数来伪装它。我想知道我是否只是在为自己创造更多的工作。

这就是我一直在伪造数字 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))
4

6 回答 6

23

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

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

(1 2 3 4 101 6)

要按索引查找,您可以使用position功能

(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)

我在这个函数索引中找到了这些。

于 2008-09-05T04:33:41.173 回答
11
  1. 在列表中找到某物的索引。

在 Emacs Lisp 和 Common Lisp 中,您具有以下position功能:

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

在 Scheme 中,这是DrScheme文档中的尾递归实现:

(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甚至是某种 Lisp 对象系统,例如 CLOS。

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

干杯!

于 2008-09-10T12:51:06.053 回答
7

答案:

  1. (位置项序列&key from-end (start 0) end key test test-not)
    http://lispdoc.com/?q=position&search=Basic+search

  2. (setf (elt 序列索引) 值)

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

于 2008-09-15T14:49:32.810 回答
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))
于 2008-09-05T12:32:51.223 回答
4

“实用通用 Lisp” +2。它是一本 Common Lisp Cookbook 和一本优质的 Teach Yourself Lisp 书的混合体。

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

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

于 2008-09-15T20:27:11.220 回答
0

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

于 2008-09-10T12:26:04.817 回答