代码之家  ›  专栏  ›  技术社区  ›  helloandre

在Lisp中列出操作

  •  7
  • helloandre  · 技术社区  · 16 年前

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

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

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

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

      (return InThisList ItemAtThisIndex)
      

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

    我就是这样假装的第一个:

    (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 回复  |  直到 6 年前
        1
  •  23
  •   Jeremy Meo    6 年前

    你可以使用 setf nth 按索引替换和检索值。

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

        2
  •  11
  •   Sébastien RoccaSerra    16 年前
    1. 在列表中查找某物的索引。

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

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

    在方案中,这里是一个尾部递归实现,来自 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 甚至是像CLOS这样的Lisp对象系统。

    如果你在学口齿不清,一定要看看 Practical Common Lisp 和/或 The Little Schemer .

    干杯!

        3
  •  7
  •   Eric Normand    16 年前

    答案:

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

    2. (SETF(ELT序列索引)值)

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

        4
  •  4
  •   Please delete this account    16 年前

    杰里米的答案应该是有效的,但那就是说,如果你发现自己写的代码

    (SETF(我的第N个列表)新ELT)

    您可能使用了错误的数据结构。列表只是简单的链接列表,所以它们可以通过索引访问。你最好使用数组。

    或者你用列表作为元组。那样的话,他们应该会没事的。但您可能想命名访问器,这样阅读代码的人就不必记住“nth 4”的含义。类似的东西

    (defun my-attr (list)
      (nth 4 list))
    
    (defun (setf my-attr) (new list)
      (setf (nth 4 list) new))
    
        5
  •  4
  •   Will    16 年前

    + 2 为“实用的共同口齿不清”。它是一本常见的口齿不清食谱和一本高质量自学口齿不清书的混合体。

    还有“成功的共同口齿不清症”( http://www.psg.com/~dlamkins/sl/cover.html http://www.psg.com/~dlamkins/sl/contents.html )这似乎填补了“实用的通用Lisp”中的一些空白/扩展了一些内容。

    我还阅读了PaulGraham的“ansi common lisp”,它更多的是关于语言的基础知识,但更多的是一个参考手册。

        6
  •  0
  •   ujh    16 年前

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