Список операций в Лиспе - PullRequest
       21

Список операций в Лиспе

7 голосов
/ 05 сентября 2008

Я искал всюду следующую функциональность в Лиспе и ничего не получил:

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

Ответы [ 6 ]

23 голосов
/ 05 сентября 2008

Вы можете использовать setf и nth для замены и извлечения значений по индексу.

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

Я нашел все эти в этом индексе функций .

11 голосов
/ 10 сентября 2008
  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.

Если вы изучаете Лисп, убедитесь, что вы изучили Практический Общий Лисп и / или Маленький интриган .

Ура!

7 голосов
/ 15 сентября 2008

Ответы:

  1. (последовательность элементов позиции и ключ от конца (начало 0), тест конца ключа не проверен)
    http://lispdoc.com/?q=position&search=Basic+search

  2. (setf (индекс последовательности elt))

  3. (индекс последовательности elt)
    http://lispdoc.com/?q=elt&search=Basic+search
    ПРИМЕЧАНИЕ: elt предпочтительнее nth, поскольку elt работает с любой последовательностью, а не только со списками

4 голосов
/ 16 сентября 2008

+ 2 для "Практического Общего Лисп". Это смесь поваренной книги Common Lisp и качественной книги «Учите себя на Лиспе».

Есть также "Успешный общий Лисп" (http://www.psg.com/~dlamkins/sl/cover.html и http://www.psg.com/~dlamkins/sl/contents.html), который, похоже, заполнил несколько пробелов / расширений в "Практическом общем Лиспе".

Я также читал «ANSI Common Lisp» Пола Грэма, который больше посвящен основам языка, но немного больше справочного руководства.

4 голосов
/ 05 сентября 2008

Джереми ответы должны работать; но, тем не менее, если вы обнаружите, что пишете код вроде

(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))
0 голосов
/ 10 сентября 2008

Я должен согласиться с Томасом. Если вы используете списки, такие как массивы, то это будет медленно (и, возможно, неловко). Поэтому вы должны либо использовать массивы, либо придерживаться написанных вами функций, но переместить их «вверх» таким образом, чтобы позже можно было легко заменить медленные списки массивами.

...