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 Answer 1

2

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)  |
3
  • 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, 2017 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, 2017 at 0:19
  • thanks for the note. I have edited the answer to use cl-position. Apr 28, 2017 at 0:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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