tags:

views:

122

answers:

5

I want to take an interval of a vector in Scheme. I know there is a procedure named vector->values, but seems like it returns each element separately, while I want to get the result as a vector. How can I achieve this?

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

while I need:

#(1 2 3)
A: 

you want subvector:

(subvector (vector 1 2 3 4 5) 0 3)
Tordek
seems like drscheme doesn't have the procedure subvector :(
Hellnar
MIT Scheme, but not in the Scheme standard.
Rainer Joswig
+2  A: 

The Scheme R6RS standard has make-vector, vector-ref, vector-set! and vector-length. With that you can write your own function subvector, which does not seem to be part of R6RS (!). Some Scheme implementation have something like subvector already.

You can also switch to Common Lisp, which provides the function SUBSEQ in the standard.

Rainer Joswig
+3  A: 

If you're using PLT, you have a few easy ways to get this:

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

The last one is probably going to be the fastest. The reason that there is no such operation that is built-in is that people usually don't do that. When you're dealing with vectors in Scheme, you're usually doing so because you want to optimize something so returning a vector and a range instead of allocating a new one is more common.

(And if you think that this is useful, please suggest it on the PLT mailing list.)

Eli Barzilay
This is 100 times better than my solution.
Andrew Song
Looks like PLT specific. How about a portable Scheme version?
Rainer Joswig
Rainer, if you care about it, feel free to make it yourself. I'll just ignore the flame attempts and get real work done instead.
Eli Barzilay
I'll wait for your portable CL GUI system, or thread or whatever.All are portable part of PLT, the language I'm programming in.
Eli Barzilay
No problem all of them are portable in LispWorks. Getting sub sequences is more basic, and really should be part of a standard Scheme library. Symptomatic that three answers fail to provide a portable solution. A 'standard lib' would be useful. Maybe there is even a SRFI for it. Why drag people to a specific Scheme, when such basic stuff like sub vectors should be there?
Rainer Joswig
"Scheme" is as much of a myth for real programming tasks as "Common Lisp" is. I could have written a portable version, I could have even used a srfi as grettke did -- but like I said, I prefer to get work done instead.
Eli Barzilay
+1  A: 
#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? Yes, very. But it only took two minutes to write and gets the job done.

(I find it's generally easier to play with lists in Scheme)

Andrew Song
Looks like *add1* and *empty* are not in the Scheme standard.
Rainer Joswig
+2  A: 

Here is a portable R6RS version using SRFI 43:

#!r6rs

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

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