Frage

I'm starting scheme for Gimp script-fu and I don't find a simple way to remove item from a vector.

My only solution is to:

  1. Convert vector to list
  2. Remove item from the list (http://stackoverflow.com/questions/1905222/how-to-delete-an-element-from-a-list-in-scheme)
  3. Convert list to vector

Is it a simplier way?

Here is my code:

(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)))))))
War es hilfreich?

Lösung

That's the way: you need to create a new vector without the element that needs to be removed, copying all the others. But in your code, you're missing the case where the element is not present in the vector, also you don't need to create an intermediate list, go from vector to vector directly. I wrote this with Racket using standard Scheme, it should be easy enough to adapt for 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)))

Use it like this:

(define myvector #(1 2 3))
(set! myvector (vector-delete myvector 3))
myvector
=> '#(1 2)

Andere Tipps

Or by a more intuitive way :

(define (vector-delete v i)
  (vector-append (vector-take v i) (vector-drop v (+ i 1)))) 
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top