2009-10-23 4 views
2

Je veux prendre un intervalle d'un vecteur dans le schéma. Je sais qu'il existe une procédure nommée vector->values, mais il semble qu'elle renvoie chaque élément séparément, alors que je veux obtenir le résultat en tant que vecteur. Comment puis-je atteindre cet objectif?obtenir un intervalle d'un vecteur

> (vector->values (vector 1 2 3 4 5) 0 3) 
1 
2 
3 

alors que je besoin:

#(1 2 3) 

Répondre

3

Si vous utilisez PLT, vous avez quelques moyens faciles pour obtenir ceci:

(define (subvector v start end) 
    (list->vector (for/list ([i (in-vector v start end)]) i))) 

(define (subvector v start end) 
    (build-vector (- end start) (lambda (i) (vector-ref v (+ i start))))) 

(define (subvector v start end) 
    (define new (make-vector (- end start))) 
    (vector-copy! new 0 v start end) 
    new) 

Le dernier va probablement être le plus rapide. La raison pour laquelle une telle opération n'est pas intégrée est que les gens ne le font pas habituellement. Lorsque vous traitez des vecteurs dans Scheme, vous le faites généralement parce que vous voulez optimiser quelque chose, donc le retour d'un vecteur et une plage au lieu d'en allouer un nouveau sont plus courants.

(Et si vous pensez que cela est utile, s'il vous plaît suggérer sur la liste de diffusion du PLT.)

+0

Ceci est 100 fois mieux que ma solution –

+0

Apparemment comme une version PLT spécifique, et une version Scheme portable? –

+1

Rainer, si cela vous intéresse, n'hésitez pas à le faire vous-même. Je vais juste ignorer la flamme atte Mpts et obtenir un vrai travail à la place. –

0

vous voulez subvector:

(subvector (vector 1 2 3 4 5) 0 3) 
+1

semble être drscheme n'a pas la procédure :( – Hellnar

+0

MIT subvector Schéma, mais pas dans la norme Scheme –

2

La norme Scheme R6RS a make-vector, vecteur-ref, vecteur-set ! et longueur de vecteur. Avec cela, vous pouvez écrire votre propre fonction sous-vecteur, qui ne semble pas faire partie de R6RS (!). Certaines implémentations de Schéma ont quelque chose comme sous-vecteur déjà.

Vous pouvez également passer à Common Lisp, qui fournit la fonction SUBSEQ dans la norme.

1
#lang scheme 
(define (my-vector-value v l h c) 
    (if (and (>= c l) (< c h)) 
     (cons (first v) (my-vector-value (rest v) l h (add1 c))) 
     empty)) 

(list->vector (my-vector-value (vector->list (vector 1 2 3 4 5)) 0 3 0)) 

Ghetto? Oui très. Mais cela n'a pris que deux minutes pour écrire et faire le travail.

(je trouve qu'il est généralement plus facile de jouer avec des listes dans le schéma)

+0

On dirait que * add1 * et * empty * ne sont pas dans la norme Scheme. –

2

Voici une version R6RS portable en utilisant SRFI 43:

#!r6rs 

(import (rnrs base) 
     (prefix (srfi :43) srfi/43:)) 

(srfi/43:vector-copy (vector 1 2 3 4 5) 0 3)