Вопрос

Я повсюду искал следующую функциональность в 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))
Это было полезно?

Решение

Вы можете использовать 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)

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

Другие советы

  1. найти индекс чего-либо в списке.

В Emacs Lisp и Common Lisp у вас есть position функция:

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

В Scheme вот реализация хвостовой рекурсии из ДокторСхемадокумент:

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

Если вы изучаете Лисп, обязательно посмотрите Практический Common Lisp и/или Маленький интриган.

Ваше здоровье!

Ответы:

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

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

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

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

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

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

Еще есть «Успешный Common Lisp» (http://www.psg.com/~dlamkins/sl/cover.html и http://www.psg.com/~dlamkins/sl/contents.html), который, казалось, заполнил несколько пробелов/расширил возможности «Practical Common Lisp».

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top