views:

1168

answers:

6

I have been searching everywhere for this functionality in lisp, and have gotten nowhere.

  1. find the index of something in a list. example:

    (index-of item InThisList)

  2. replace something at a specific spot in a list. example:

    (replace item InThisList AtThisIndex) ;i think this can be done with 'setf'?

  3. return an item at a specific index. example:

    (return InThisList ItemAtThisIndex)

Up until this point, i've been faking it with my own functions. I'm wondering if i'm just creating more work for myself.

This is how i've been faking number 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))
+15  A: 

I'm a noob myself, but you can use setf and nth to do number 2 and 3.

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

(1 2 3 4 101 6)

No clue about number one.

EDIT: For number one you can use the position function. Ha.

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

I found these all in this index.

Jeremy Banks
+2  A: 

Jeremy's answers should work; but that said, if you find yourself writing code like

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

you're probably using the wrong datastructure. Lists are simply linked lists, so they're O(N) to access by index. You might be better off using arrays.

Or maybe you're using lists as tuples. In that case, they should be fine. But you probably want to name accessors so someone reading your code doesn't have to remember what "nth 4" is supposed to mean. Something like

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

(defun (setf my-attr) (new list)
  (setf (nth 4 list) new))
Also, we aren't 'replacing' an element in a list. We're copying the first (r-1) elements and putting the new value in r, where it's cdr is connected to the (r+1) element --since we are dealing with persistence.
nlucaroni
A: 

I have to agree with Thomas. If you use lists like arrays then that's just going to be slow (and possibly awkward). So you should either use arrays or stick with the functions you've written but move them "up" in a way so that you can easily replace the slow lists with arrays later.

ujh
+4  A: 
  1. find the index of something in a list.

In Emacs Lisp and Common Lisp, you have the position function:

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

In Scheme, here's a tail recursive implementation from DrScheme's 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
>

But if you're using a list as a collection of slots to store structured data, maybe you should have a look at defstruct or even some kind of Lisp Object System like CLOS.

If you're learning Lisp, make sure you have a look at Practical Common Lisp and / or The Little Schemer.

Cheers!

Sébastien RoccaSerra
+2  A: 

Answers:

  1. (position item sequence &key from-end (start 0) end key test test-not)
    http://lispdoc.com/?q=position&amp;search=Basic+search

  2. (setf (elt sequence index) value)

  3. (elt sequence index)
    http://lispdoc.com/?q=elt&amp;search=Basic+search
    NOTE: elt is preferable to nth because elt works on any sequence, not just lists

Eric Normand
+3  A: 

+2 for "Practical Common Lisp". It is a mixture of a Common Lisp Cookbook and a quality Teach Yourself Lisp book.

There's also "Successful Common Lisp" (http://www.psg.com/~dlamkins/sl/cover.html and http://www.psg.com/~dlamkins/sl/contents.html) which seemed to fill a few gaps / extend things in "Practical Common Lisp".

I've also read Paul Graham's "ANSI Common Lisp" which is more about the basics of the language, but a bit more of a reference manual.