0

I know subseq in lisp return a subsequence through a range. Is there anything which will return the subsequence except that range and should be non-destructive? Any help is appreciated.

coredump
  • 37,664
  • 5
  • 43
  • 77
Anowarul Kabir
  • 47
  • 1
  • 1
  • 6
  • 2
    There's nothing built-in. Get the subsequence before the range and the subsequence after it, and then concatenate them with `nconc`. – Barmar Apr 07 '19 at 04:33

2 Answers2

2

You can do it for any sequence with concatenate and subseq:

(defun sequence-except (sequence start end)
  (concatenate (sequence-type sequence)
               (subseq sequence 0 start)
               (subseq sequence end)))

The following should be enough to determine the type of the input sequence for bit-vectors, strings, etc:

(defun sequence-type (sequence)
  (etypecase sequence
    (list 'list)
    (array `(array ,(array-element-type sequence) (*)))))

Tests:

(loop for test in (list
                   #*10101001
                   "abcd"
                   '(0 3 2)
                   nil
                   #(1 2 3 4)
                   (make-array 4
                               :adjustable t
                               :fill-pointer T
                               :initial-contents
                               '(a b c d)))
      collect (concatenate (sequence-type test) test))
coredump
  • 37,664
  • 5
  • 43
  • 77
0

can't you just:

(defun seq-drop-subseq (SEQ START &optional END)
  (if END
      (nconc (seq-take START) (seq-drop END))
    (seq-take START)))

edit: had to go look. remove does it.

l.k
  • 199
  • 8