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

Your Answer

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

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