From: localhost
Subject: Sort List of CLOS Objects
Date: 
Message-ID: <1187023548.295411.178500@j4g2000prf.googlegroups.com>
I'd like to sort a list of CLOS objects by a string value in one of
the object's slots. What would be the best way to do this?

For instance, I have a deck of cards...


(defparameter *deck* nil)
(defparameter *values* '(:a :k :q :j :10 :9 :8 :7 :6 :5 :4 :3 :2))
(defparameter *suites* '(:spades :hearts :diamonds :clubs))

;;; Create the card object.
(defclass card ()
           ((value :reader get-card-value
                   :writer set-card-value
                   :initarg :card-value)
            (suite :reader get-card-suite
                   :writer set-card-suite
                   :initarg :card-suite)))

;;; Populate the deck with cards.
(dolist (suite *suites*)
           (dolist (value *values*)
             (push (make-instance 'card :card-value value :card-suite
suite)
                   *deck*)))


...how would one sort the *card* list based on value or suite? I've
looked into using "sort" with "string>=", but can't picture how or
where to use the (symbol-name (get-card-value)) or (symbol-name (get-
card-suite)).

If I can do a simple sort by by "string>=", I'm sure I can progress to
a random sort (shuffle). For now I'm not seeing it, though.

Thanks in advance.

From: Zach Beane
Subject: Re: Sort List of CLOS Objects
Date: 
Message-ID: <m33aynfjf7.fsf@unnamed.xach.com>
localhost <··········@frontiernet.net> writes:

> ...how would one sort the *card* list based on value or suite? I've
> looked into using "sort" with "string>=", but can't picture how or
> where to use the (symbol-name (get-card-value)) or (symbol-name (get-
> card-suite)).

STRING>= takes a string designator, and a symbol is a fine string
designator (it designates the string that is the symbol-name of the
symbol). Also, SORT takes a keyword argument KEY that will produce an
object to use in place of the original object for the purposes of
comparison. So you could use those two ideas to do something like:

   (setf *card* (sort *card* #'string>= :key #'get-card-value))

Zach
From: Rob St. Amant
Subject: Re: Sort List of CLOS Objects
Date: 
Message-ID: <f9qc9h$b2l$1@blackhelicopter.databasix.com>
localhost <··········@frontiernet.net> writes:

> I'd like to sort a list of CLOS objects by a string value in one of
> the object's slots. What would be the best way to do this?
>
> For instance, I have a deck of cards...
>
>
> (defparameter *deck* nil)
> (defparameter *values* '(:a :k :q :j :10 :9 :8 :7 :6 :5 :4 :3 :2))
> (defparameter *suites* '(:spades :hearts :diamonds :clubs))
>
> ;;; Create the card object.
> (defclass card ()
>            ((value :reader get-card-value
>                    :writer set-card-value
>                    :initarg :card-value)
>             (suite :reader get-card-suite
>                    :writer set-card-suite
>                    :initarg :card-suite)))
>
> ;;; Populate the deck with cards.
> (dolist (suite *suites*)
>            (dolist (value *values*)
>              (push (make-instance 'card :card-value value :card-suite
> suite)
>                    *deck*)))
>
>
> ...how would one sort the *card* list based on value or suite? I've
> looked into using "sort" with "string>=", but can't picture how or
> where to use the (symbol-name (get-card-value)) or (symbol-name (get-
> card-suite)).
>
> If I can do a simple sort by by "string>=", I'm sure I can progress to
> a random sort (shuffle). For now I'm not seeing it, though.

If you're using this example to learn Lisp, here are a couple of other
things you might think about.  (As an aside, "rank" and "suit" are
more common terms than your "value" and "suite".)

It's not clear why you want writer methods on cards; their rank and
suit tend to stay constant.  You might also think about whether
face-up or face-down should be part of a card definition (and this
would be changeable, of course).

It will probably be easier in your coding if you have *values* contain
just numbers ranging from 1 to 13.  You'd translate 1 to A, 11 to J,
etc. in a print-object method.

You should be able to do a random sort entirely without reference to
the identity of the card objects.
From: localhost
Subject: Re: Sort List of CLOS Objects
Date: 
Message-ID: <1187035755.864162.308420@m37g2000prh.googlegroups.com>
On Aug 13, 12:43 pm, ·······@ncsu.edu (Rob St. Amant) wrote:
> localhost <··········@frontiernet.net> writes:
> > I'd like to sort a list of CLOS objects by a string value in one of
> > the object's slots. What would be the best way to do this?
>
> > For instance, I have a deck of cards...
>
> > (defparameter *deck* nil)
> > (defparameter *values* '(:a :k :q :j :10 :9 :8 :7 :6 :5 :4 :3 :2))
> > (defparameter *suites* '(:spades :hearts :diamonds :clubs))
>
> > ;;; Create the card object.
> > (defclass card ()
> >            ((value :reader get-card-value
> >                    :writer set-card-value
> >                    :initarg :card-value)
> >             (suite :reader get-card-suite
> >                    :writer set-card-suite
> >                    :initarg :card-suite)))
>
> > ;;; Populate the deck with cards.
> > (dolist (suite *suites*)
> >            (dolist (value *values*)
> >              (push (make-instance 'card :card-value value :card-suite
> > suite)
> >                    *deck*)))
>
> > ...how would one sort the *card* list based on value or suite? I've
> > looked into using "sort" with "string>=", but can't picture how or
> > where to use the (symbol-name (get-card-value)) or (symbol-name (get-
> > card-suite)).
>
> > If I can do a simple sort by by "string>=", I'm sure I can progress to
> > a random sort (shuffle). For now I'm not seeing it, though.
>
> If you're using this example to learn Lisp, here are a couple of other
> things you might think about.  (As an aside, "rank" and "suit" are
> more common terms than your "value" and "suite".)
>
> It's not clear why you want writer methods on cards; their rank and
> suit tend to stay constant.  You might also think about whether
> face-up or face-down should be part of a card definition (and this
> would be changeable, of course).
>
> It will probably be easier in your coding if you have *values* contain
> just numbers ranging from 1 to 13.  You'd translate 1 to A, 11 to J,
> etc. in a print-object method.
>
> You should be able to do a random sort entirely without reference to
> the identity of the card objects.

Thanks all for the responses.

Yes, I am just learning CLOS. I've ordered Keene's "Object-Oriented
Programming in Common Lisp", but cannot resist toying with CLOS before
the book arrives.

Using integers as the ranks makes plenty of sense. I had considered
using a list (:k . 12), but that would have made sorting slightly
tougher.

Correct, the writers are unneeded as :initarg for assignment is being
used and the values will not change.

Thanks again.
From: ··········@hotmail.com
Subject: Re: Sort List of CLOS Objects
Date: 
Message-ID: <1187084013.044025.266740@22g2000hsm.googlegroups.com>
> Yes, I am just learning CLOS. I've ordered Keene's "Object-Oriented
> Programming in Common Lisp", but cannot resist toying with CLOS before
> the book arrives.

This guide covers most usercases of clos:
http://www.aiai.ed.ac.uk/~jeff/clos-guide.html

This guide explains what happens under the hood and is useful the day
you need to reload an defclass:
http://www.ravenbrook.com/doc/2003/07/15/clos-fundamentals/

Besides PCL, I havn't found any other stuff that comes as close to
being clean and easy to understand as these two guides.
From: Brian Connoy
Subject: Re: Sort List of CLOS Objects
Date: 
Message-ID: <46C19E54.2AAF.0024.0@morrisonhershfield.com>
> Yes, I am just learning CLOS. I've ordered Keene's "Object-Oriented
> Programming in Common Lisp", but cannot resist toying with CLOS before
> the book arrives.

This book may prove hard to track down, but I find it's a nice complement to
Keene.

"Understanding CLOS: The Common Lisp Object System", by Jo A. Lawless &
Molly M. Miller
ISBN: 1-55558-064-5
From: Pascal Costanza
Subject: Re: Sort List of CLOS Objects
Date: 
Message-ID: <5ibi0lF3l15qmU1@mid.individual.net>
localhost wrote:
> I'd like to sort a list of CLOS objects by a string value in one of
> the object's slots. What would be the best way to do this?
> 
> For instance, I have a deck of cards...
> 
> 
> (defparameter *deck* nil)
> (defparameter *values* '(:a :k :q :j :10 :9 :8 :7 :6 :5 :4 :3 :2))
> (defparameter *suites* '(:spades :hearts :diamonds :clubs))
> 
> ;;; Create the card object.
> (defclass card ()
>            ((value :reader get-card-value
>                    :writer set-card-value
>                    :initarg :card-value)
>             (suite :reader get-card-suite
>                    :writer set-card-suite
>                    :initarg :card-suite)))
> 
> ;;; Populate the deck with cards.
> (dolist (suite *suites*)
>            (dolist (value *values*)
>              (push (make-instance 'card :card-value value :card-suite
> suite)
>                    *deck*)))
> 
> 
> ...how would one sort the *card* list based on value or suite? I've
> looked into using "sort" with "string>=", but can't picture how or
> where to use the (symbol-name (get-card-value)) or (symbol-name (get-
> card-suite)).

Pass a :key parameter to sort.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ariel Badichi
Subject: Re: Sort List of CLOS Objects
Date: 
Message-ID: <87k5rzuo92.fsf@sneeze.site>
localhost <··········@frontiernet.net> writes:

> If I can do a simple sort by by "string>=", I'm sure I can progress to
> a random sort (shuffle). For now I'm not seeing it, though.

Others have answered your question, so I'll only remark that according
to the CLHS, the predicate must be a strict relation, i.e. irreflexive,
asymmetric, and transitive.  STRING>= is not a strict relation.

See the entry for SORT for more information.