Схема: Как удалить / удалить элемент из вектора

Я запускаю схему для Gimp script-fu и не нахожу простой способ удалить элемент из вектора.

Мое единственное решение состоит в том, чтобы:

  1. Преобразовать вектор в список
  2. Удалить элемент из списка (http://stackru.com/questions/1905222/how-to-delete-an-element-from-a-list-in-scheme)
  3. Конвертировать список в вектор

Это более простой способ?

Вот мой код:

(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)))) 
Другие вопросы по тегам