0

Q:  Each sub-list within the main list contains one of five possible categories. How can I customize the sort in the following order:

CUSTOM SORT ORDER:

1.  TASKS

2.  EVENTS

3.  UNDATED

4.  CONTACTS

5.  DONE

BEGIN WITH:

'((("id" . "005") ("folder" . "EVENTS") ("misc" . "apples") ("foo" . "1"))
  (("id" . "123") ("folder" . "CONTACTS") ("misc" . "oranges") ("foo" . "3"))
  (("id" . "975") ("folder" . "UNDATED") ("misc" . "figs") ("foo" . "7"))
  (("id" . "456") ("folder" . "TASKS") ("misc" . "bananas") ("foo" . "5"))
  (("id" . "871") ("folder" . "DONE") ("misc" . "pears") ("foo" . "2"))
  (("id" . "045") ("folder" . "EVENTS") ("misc" . "plums") ("foo" . "8"))
  (("id" . "172") ("folder" . "CONTACTS") ("misc" . "avocados") ("foo" . "4"))
  (("id" . "843") ("folder" . "UNDATED") ("misc" . "nectarines") ("foo" . "6"))
  (("id" . "523") ("folder" . "TASKS") ("misc" . "onions") ("foo" . "10"))
  (("id" . "278") ("folder" . "DONE") ("misc" . "coconuts") ("foo" . "9")))

END-WITH:  (a secondary sort, after sorting by 5 categories is not required in this example).

'((("id" . "523") ("folder" . "TASKS") ("misc" . "onions") ("foo" . "10"))
  (("id" . "456") ("folder" . "TASKS") ("misc" . "bananas") ("foo" . "5"))
  (("id" . "005") ("folder" . "EVENTS") ("misc" . "apples") ("foo" . "1"))
  (("id" . "045") ("folder" . "EVENTS") ("misc" . "plums") ("foo" . "8"))
  (("id" . "975") ("folder" . "UNDATED") ("misc" . "figs") ("foo" . "7"))
  (("id" . "843") ("folder" . "UNDATED") ("misc" . "nectarines") ("foo" . "6"))
  (("id" . "172") ("folder" . "CONTACTS") ("misc" . "avocados") ("foo" . "4"))
  (("id" . "123") ("folder" . "CONTACTS") ("misc" . "oranges") ("foo" . "3"))
  (("id" . "871") ("folder" . "DONE") ("misc" . "pears") ("foo" . "2"))
  (("id" . "278") ("folder" . "DONE") ("misc" . "coconuts") ("foo" . "9")))
1

Here is one solution. It doesn't give exactly the order you specified, but they are sorted by folder.

#+BEGIN_SRC emacs-lisp
(sort '((("id" . "005") ("folder" . "EVENTS") ("misc" . "apples") ("foo" . "1"))
    (("id" . "123") ("folder" . "CONTACTS") ("misc" . "oranges") ("foo" . "3"))
    (("id" . "975") ("folder" . "UNDATED") ("misc" . "figs") ("foo" . "7"))
    (("id" . "456") ("folder" . "TASKS") ("misc" . "bananas") ("foo" . "5"))
    (("id" . "871") ("folder" . "DONE") ("misc" . "pears") ("foo" . "2"))
    (("id" . "045") ("folder" . "EVENTS") ("misc" . "plums") ("foo" . "8"))
    (("id" . "172") ("folder" . "CONTACTS") ("misc" . "avocados") ("foo" . "4"))
    (("id" . "843") ("folder" . "UNDATED") ("misc" . "nectarines") ("foo" . "6"))
    (("id" . "523") ("folder" . "TASKS") ("misc" . "onions") ("foo" . "10"))
    (("id" . "278") ("folder" . "DONE") ("misc" . "coconuts") ("foo" . "9")))
      (lambda (el1 el2)
    (let ((order '("TASKS" "EVENTS" "UNDATED" "CONTACTS" "DONE")))
      (< (cl-position (cdr (assoc "folder" el1)) order :test 'string=)
         (cl-position (cdr (assoc "folder" el2)) order :test 'string=)))))
#+END_SRC

#+RESULTS:
| (id . 456) | (folder . TASKS)    | (misc . bananas)    | (foo . 5)  |
| (id . 523) | (folder . TASKS)    | (misc . onions)     | (foo . 10) |
| (id . 005) | (folder . EVENTS)   | (misc . apples)     | (foo . 1)  |
| (id . 045) | (folder . EVENTS)   | (misc . plums)      | (foo . 8)  |
| (id . 975) | (folder . UNDATED)  | (misc . figs)       | (foo . 7)  |
| (id . 843) | (folder . UNDATED)  | (misc . nectarines) | (foo . 6)  |
| (id . 123) | (folder . CONTACTS) | (misc . oranges)    | (foo . 3)  |
| (id . 172) | (folder . CONTACTS) | (misc . avocados)   | (foo . 4)  |
| (id . 871) | (folder . DONE)     | (misc . pears)      | (foo . 2)  |
| (id . 278) | (folder . DONE)     | (misc . coconuts)   | (foo . 9)  |
  • Nice canonical answer. Only thing is that position should really be cl-position and maybe you should require cl-seq or cl-lib. – Tobias Apr 28 '17 at 0:11
  • I just had a further look. position is from cl-compat which is obsolete. cl-position is auto-loaded in emacs -Q so you do not really need to require anything if you use cl-position. – Tobias Apr 28 '17 at 0:19
  • thanks for the note. I have edited the answer to use cl-position. – John Kitchin Apr 28 '17 at 0:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.