8000
Skip to content

Add remove-index to racket/list#2547

Open
LeifAndersen wants to merge 1 commit intoracket:masterfrom
Le 8000 ifAndersen:remove-index
Open

Add remove-index to racket/list#2547
LeifAndersen wants to merge 1 commit intoracket:masterfrom
LeifAndersen:remove-index

Conversation

@LeifAndersen
Copy link
Copy Markdown
Member

Its surprisingly missing.

(This initial commit doesn't add documents and tests. They should obviously be added before merging.)

@gus-massa
Copy link
Copy Markdown
Contributor

I'm not sure if this is the usual definition somewhere, but I expect (remove-index '(0 1 2 3) 99), similar to the error generated by (list-ref '(0 1 2 3) 99). (I'm not 100% sure what is better here.)

Also, I expect that the tail of the list is preserved, so

(define l (list 0 1 2 3 4))
(eq? (cdr (remove-index l 1))
     (cddr l) )                ; ==> #t 

@AlexKnauth
Copy link
Copy Markdown
Member

A definition of remove-index that meets @gus-massa's suggestions could be something like this:

;; remove-index : [Listof X] Nat -> [Listof X]
;; Removes the element at the given index in the list, such that
;; (take (remove-index ls idx) idx) stays equal? to (take ls idx), and
;; (drop (remove-index ls idx) idx) is eq? to (drop ls (add1 idx)).
(define (remove-index ls idx)
  (unless (list? ls)
    (raise-argument-error 'remove-index "list?" 0 ls idx))
  (unless (exact-nonnegative-integer? idx)
    (raise-argument-error 'remove-index "exact-nonnegative-integer?" 1 ls idx))
  (let loop ([lst ls] [i idx])
    (unless (pair? lst)
      (raise-arguments-error 'remove-index
                             "index is too big for list"
                             "list" ls
                             "index" idx))
    (cond [(zero? i) (cdr lst)]
          [else      (cons (car lst) (loop (cdr lst) (sub1 i)))])))
(module+ test
  (require rackunit)
  (define l (list 0 1 2 3 4))
  (check-eq? (cdr (remove-index l 1))
             (cddr l))
  (check-equal? (take (remove-index l 3) 3)
                (take l 3))
  (check-eq? (drop (remove-index l 2) 2)
             (drop l (add1 2)))
  (check-eq? (drop (remove-index l 3) 3)
             (drop l (add1 3)))
  (check-exn #rx"index is too big for list.*index: *99"
             (λ () (remove-index '(0 1 2 3) 99))))

@shhyou shhyou added the api design Related to the design of core libraries and language features label Nov 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api design Related to the design of core libraries and language features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

0