0

I want to do something that looks similar to replace but performs different operation.
Using replace will create a new vector containing the corresponding value(s) of the index provided.

example

(replace [10 9 8 7 6] [0 4])     ;;=> [10 6]

My question now is that is there a way to create a new vector that will exclude the corresponding value(s) of the index provided? i.e delete the values of the index provided from the vector.

the code below is just an illustration. "some-function means something needs to be there"  
( 'some-function'   [10 9 8 7 6] [0 4])    ;;=> [9 8 7]
1
  • Are you, as some answers suggest, deleting a subrange, always given by two indexes? Or, as others assume, are you providing a sequence of any number of indexes to delete the values of? Commented Aug 8, 2015 at 11:11

4 Answers 4

1

I don't know of a native function that does what you want. If you were working with Maps you could use dissoc.

You can write your own function to do this. Here is one way (of many) below.

(defn dissoc-vec
  ([v ks]
    (let [pred (set ks)
          replace-keys (->> (range (count v))
                            (remove #(pred %))
                            vec)]
      (replace v replace-keys))))
Sign up to request clarification or add additional context in comments.

3 Comments

Note that this takes linear time while dissoc is a nearly constant time op.
This has to take linear time, because the vector data structure does not have a way to support fast indexed removal.
Your (remove #(pred %)) is just (remove pred), as @amalloy once pointed out to me :).
0

check out subvec.

to achieve the exact function you want, you can do this:

(fn [coll [a b]]
  (subvec coll (inc a) b))

3 Comments

Note that a vector returned by subvec only returns a view on the input vector, hence the input vector won't be garbage collected.
Also you can't productively conj elements back onto the subvector, without it internally copying the original vector anyway.
@amalloy Do you have a reference?
0

You probably need https://github.com/clojure/core.rrb-vector

[...]clojure.core.rrb-vector/subvec, which produces a new vector containing the appropriate subrange of the input vector (in contrast to clojure.core/subvec, which returns a view on the input vector).

Comments

0

You can do this with the sequence functions as follows:

(defn remove-indexes [indexes coll]
  (->> coll
       (map-indexed vector)
       (remove (comp (set indexes) first))
       (map second)
       vec))

(remove-indexes [0 4] [10 9 8 7 6])
;[9 8 7]
  • I've switched the arguments around to correspond with core remove.
  • Since it works on any collection, you might omit the final vec.

A transducer version is probably a bit quicker:

(defn remove-indexes [is v]
  (into [] 
        (comp (map-indexed vector)
              (remove (comp (set is) first))
              (map second))
        v))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.