sorting an assoc list using the cdr of each sub-list

sorting an assoc list using the cdr of each sub-list

Post by ccc3180 » Sun, 13 Dec 2009 07:40:26


Suppose I have a list:
(setf test-occ '((E . 1) (C . 2) (B . 3) (D . 5) (A . 4)))

and I want to sort it in numerical order like this:
((D . 5) (A . 4) (B . 3) (C . 2) (E . 1)))

Looking at the sort function, I've tried for the past two days to come
up with something. This does what I want:
(< (cdr (assoc (caar test-occ) test-occ)) (cdr (assoc (caadr test-occ)
test-occ)))

According to the documentation, sort works like this:
sort sequence predicate &key key => sorted-sequence

The example I have been following is this:
(setq tester (list '(1 2 3) '(4 5 6) '(7 8 9))) => ((1 2 3) (4 5 6)
(7 8 9))
(sort tester #'> :key #'car) => ((7 8 9) (4 5 6) (1 2 3))

My last effort (after many, many different trial-and-error attempts)
is:
(sort test-occ #'> :key #'cdar))

This is the error message it produces:
CDAR: C is not a LIST
[Condition of type SIMPLE-TYPE-ERROR]

Restarts:
0: [ABORT] Abort handling SLIME request.

What am I doing wrong, and how to I fix it?

Thanks, CC.
 
 
 

sorting an assoc list using the cdr of each sub-list

Post by Joshua Tay » Sun, 13 Dec 2009 07:50:37


You're very close, but you the elements you're sorting are conses, and
you want to sort them by comparing their CDRs (not their CDARs) with >.

(sort (copy-tree '((E . 1) (C . 2) (B . 3) (D . 5) (A . 4)))
'> :key 'cdr)
=> ((D . 5) (A . 4) (B . 3) (C . 2) (E . 1))

//JT

 
 
 

sorting an assoc list using the cdr of each sub-list

Post by Joshua Tay » Sun, 13 Dec 2009 07:53:14


Before anyone calls me on it---this should have been COPY-LIST. No need
to copy all the individuals pairs in the alist.
 
 
 

sorting an assoc list using the cdr of each sub-list

Post by Kenneth Ti » Sun, 13 Dec 2009 08:40:56


Is it too early to call you on not catching that the OP used CDAR (and
you reiterated it) when they meant CADR? Of course you were right that
they needed CDR, but it helps to pick up all the shards of glass in
these deals.

kt

--

http://www.yqcomputer.com/
http://www.yqcomputer.com/
 
 
 

sorting an assoc list using the cdr of each sub-list

Post by Joshua Tay » Sun, 13 Dec 2009 09:37:40


Where did the OP mean CADR? The error "C is not a list" suggests that
they were indeed trying to call CDAR on the cells (in that case (C . 2))
where they wanted CDR.

The OP tried wanted to sort an alist by the numerical values of the
values in the (key . value) pairs. With an alist of the form

((E . 1) ...)

the first value that the OP was interested was the CDAR the alist (i.e.,
1), so I can see where they might have thought that they wanted to use
CDAR as the key.

For my part, it was a bit sloppy to say ``their CDARs'' since a cons
cell does not /have/ a CDAR in the sense that it /has/ a CAR and a CDR.

//JT
 
 
 

sorting an assoc list using the cdr of each sub-list

Post by Kenneth Ti » Sun, 13 Dec 2009 10:22:20


Hmmm, I think you are right. That does make more sense that they would
do CDAR, see the 1, and go for it.

kt

--

http://www.yqcomputer.com/
http://www.yqcomputer.com/
 
 
 

sorting an assoc list using the cdr of each sub-list

Post by tar » Sun, 13 Dec 2009 10:34:37

ccc31807 < XXXX@XXXXX.COM > writes:


What you want is something like

(sort test-occ #'> :key #'cdr)

The key concept, is that the KEY function is applied to each element in
the list to be sorted, not to the entire list. So, if you look at one
element of the alist, you have

(D . 5)

And if you apply CDR to that cons pair, you will get

(cdr '(d . 5)) ==> 5

which is the value you want to use for sorting.

Now, you also need to remember that SORT is a destructive function, so
you MUST use the return value. Also, it should not be applied to
constant lists, so instead of '((E . 1) ...) you need to use (list '(E
. 1) ...) or use COPY-LIST somewhere.


What is happening here is that the CDAR function is being applied to
(C . 2)
CDAR is the same as (cdr (car ...)) so you are applying
(cdr (car '(C . 2)))
------------
=> C
(cdr 'C) => error

You are on the right track, though. You just needed to use plain CDR.

--
Thomas A. Russ, USC/Information Sciences Institute
 
 
 

sorting an assoc list using the cdr of each sub-list

Post by W. Jame » Sun, 13 Dec 2009 10:59:29


[[:E, 1], [:C, 2], [:B, 3], [:D, 5], [:A, 4]].sort_by{|a,b| -b}
==>[[:D, 5], [:A, 4], [:B, 3], [:C, 2], [:E, 1]]

--
 
 
 

sorting an assoc list using the cdr of each sub-list

Post by W. Jame » Sun, 13 Dec 2009 11:03:00


Bad grammar and bad logic.
1 isn't more than 1.
I'll help you.


--
"A woman's place is in the home." --- Wise Old Saying
 
 
 

sorting an assoc list using the cdr of each sub-list

Post by W. Jame » Sun, 13 Dec 2009 11:08:07


What a truly lame language Commune Lisp is.



Commune Lispers have the most incredible difficulty grappling with the
most mundane problems.

Is it the language?
Is it the users?
Is it both?
Cannot it be safely assumed that only lame programmers would use a lame
language?


--
 
 
 

sorting an assoc list using the cdr of each sub-list

Post by Raffael Ca » Sun, 13 Dec 2009 12:21:44

On 2009-12-11 21:08:07 -0500, "W. James" < XXXX@XXXXX.COM > said:


Cannot it be safely assumed that only the lamest of lame programmers
would spend time trolling a usenet group for a language he considers
lame?
--
Raffael Cavallaro
 
 
 

sorting an assoc list using the cdr of each sub-list

Post by Raffael Ca » Sun, 13 Dec 2009 12:22:27

On 2009-12-11 20:59:29 -0500, "W. James" < XXXX@XXXXX.COM > said:

@%#$^& NO CARRIER

--
Raffael Cavallaro
 
 
 

sorting an assoc list using the cdr of each sub-list

Post by Kenneth Ti » Sun, 13 Dec 2009 14:04:30


responses are oxygen for trolls.*

aren't you supposed to be painting?

kt

* I know, your response was so brilliant it will shut him up forever.
That has always worked before on Usenet. <sigh>

k

--

http://www.yqcomputer.com/
http://www.yqcomputer.com/
 
 
 

sorting an assoc list using the cdr of each sub-list

Post by Giorgos Ke » Sun, 13 Dec 2009 18:44:28


Each object of the pairs compared by the sort comparison is a cons cell,
so the :key has to extract its `cdr' not its `cadr':

CLISP> (sort (copy-tree *test*) #'> :key #'cdr)
((D . 5) (A . 4) (B . 3) (C . 2) (E . 1))

CLISP> (sort (copy-tree *test*) #'< :key #'cdr)
((E . 1) (C . 2) (B . 3) (A . 4) (D . 5))

The pairs of objects compared by sort are:

(E . 1) <=> (C . 2)

You can see the comparisons of `sort' by writing a custom test that
prints the objects being compared and *then* calls #'< to do the real
comparison:

CLISP> (labels ((compare (a b)
(format t "~&Comparing: ~S <=> ~S~%" a b)
(< (cdr a) (cdr b))))
(sort (copy-tree *test*) #'compare))
Comparing: (C . 2) <=> (E . 1)
Comparing: (A . 4) <=> (D . 5)
Comparing: (A . 4) <=> (B . 3)
Comparing: (B . 3) <=> (E . 1)
Comparing: (B . 3) <=> (C . 2)
=> ((E . 1) (C . 2) (B . 3) (A . 4) (D . 5))

Now it's easy to see why a plain :key #'cdr should work.
 
 
 

sorting an assoc list using the cdr of each sub-list

Post by Raffael Ca » Mon, 14 Dec 2009 02:20:08

On 2009-12-12 00:04:30 -0500, Kenneth Tilton < XXXX@XXXXX.COM > said:


which is why you're replying to me, right?

--
Raffael Cavallaro