Does Common Lisp have a something like java's Set Interface/implementing classes?

前端 未结 8 1032
无人及你
无人及你 2021-01-12 01:58

I need something like this, a collection of elements which contains no duplicates of any element. Does Common Lisp, specifically SBCL, have any thing like this?

相关标签:
8条回答
  • 2021-01-12 02:49

    Easily solvable using a hash table.

    (let ((h (make-hash-table :test 'equalp))) ; if you're storing symbols
      (loop for i from 0 upto 20
            do (setf (gethash i h) (format nil "Value ~A" i)))
      (loop for i from 10 upto 30
            do (setf (gethash i h) (format nil "~A eulaV" i)))
      (loop for k being the hash-keys of h using (hash-value v)
            do (format t "~A => ~A~%" k v)))
    

    outputs

    0 => Value 0
    1 => Value 1
    ...
    9 => Value 9
    10 => 10 eulaV
    11 => 11 eulaV
    ...
    29 => 29 eulaV
    30 => 30 eulaV
    
    0 讨论(0)
  • 2021-01-12 02:52

    You could use lists, though they can prove to be inefficient for representing large sets. This is done using ADJOIN or PUSHNEW to add a new element to a list, and DELETE or REMOVE to do the opposite.

    (let ((set (list)))
      (pushnew 11 set)
      (pushnew 42 set)
      (pushnew 11 set) 
      (print set) ; set={42,11}
      (setq set (delete 42 set))
      (print set)) ; set={11}
    

    One thing to watch out for is all that these operators use EQL by default to test for potential duplicates in the set (much as Java uses the equals method). That's OK for sets holding numbers or characters, but for sets of other objects, a `deeper' equality test such as EQUAL should be specified as a :TEST keyword parameter, e.g. for a set of strings :-

    (let ((set (list)))
      (pushnew "foo" set :test #'equal)
      (pushnew "bar" set :test #'equal)
      (pushnew "foo" set :test #'equal) ; EQUAL decides that "foo"="foo"
      (print set)) ; set={"bar","foo"}
    

    Lisp's counterparts to some of Java's Set operations are:

    • addAll -> UNION or NUNION
    • containsAll -> SUBSETP
    • removeAll -> SET-DIFFERENCE or NSET-DIFFERENCE
    • retainAll -> INTERSECTION or NINTERSECTION
    0 讨论(0)
提交回复
热议问题