Схема: Как удалить / удалить элемент из вектора
Я запускаю схему для Gimp script-fu и не нахожу простой способ удалить элемент из вектора.
Мое единственное решение состоит в том, чтобы:
- Преобразовать вектор в список
- Удалить элемент из списка (http://stackru.com/questions/1905222/how-to-delete-an-element-from-a-list-in-scheme)
- Конвертировать список в вектор
Это более простой способ?
Вот мой код:
(set! myvector (list->vector (delete item (vector->list myvector))))
(define delete
(lambda (item list)
(cond
((equal? item (car list)) (cdr list))
(else (cons (car list) (delete item (cdr list)))))))
2 ответа
Решение
Вот так: вам нужно создать новый вектор без элемента, который нужно удалить, скопировав все остальные. Но в вашем коде вы пропускаете случай, когда элемент отсутствует в векторе, а также вам не нужно создавать промежуточный список, переходить от вектора к вектору напрямую. Я написал это с помощью Racket, используя стандартную Scheme, его должно быть достаточно легко адаптировать для script-fu:
(define (vector-delete vec elt)
(let ((new-vec (if (> (vector-length vec) 0)
(make-vector (- (vector-length vec) 1))
(vector))))
(define (loop i j)
(cond ((= i (vector-length vec))
new-vec)
((equal? (vector-ref vec i) elt)
(loop (+ i 1) j))
((< j (vector-length new-vec))
(vector-set! new-vec j (vector-ref vec i))
(loop (+ i 1) (+ j 1)))
(else vec)))
(loop 0 0)))
Используйте это так:
(define myvector #(1 2 3))
(set! myvector (vector-delete myvector 3))
myvector
=> '#(1 2)
Или более интуитивным способом:
(define (vector-delete v i)
(vector-append (vector-take v i) (vector-drop v (+ i 1))))