Skip to content

Instantly share code, notes, and snippets.

@wilkerlucio
Last active June 24, 2024 03:53
Show Gist options
  • Save wilkerlucio/db54dc83a9664124f3febf6356f04509 to your computer and use it in GitHub Desktop.
Save wilkerlucio/db54dc83a9664124f3febf6356f04509 to your computer and use it in GitHub Desktop.
Alphabetical/Natural sorting in Clojure/Clojurescript
(ns util.natural-sorting
(:refer-clojure :exclude [sort sort-by])
(:require [clojure.string]))
(defn parse-int [s]
#?(:clj (Long/parseLong s)
:cljs (js/parseInt s)))
(defn vector-compare [[value1 & rest1] [value2 & rest2]]
(let [result (compare value1 value2)]
(cond
(not (zero? result)) result
(nil? value1) 0
:else (recur rest1 rest2))))
(defn prepare-string [s]
(let [s (or s "")
parts (vec (clojure.string/split s #"\d+"))
numbers (->> (re-seq #"\d+" s)
(map parse-int)
(vec))]
(vec (interleave (conj parts "") (conj numbers -1)))))
(defn natural-compare [a b]
(vector-compare (prepare-string a)
(prepare-string b)))
(defn sort [coll] (clojure.core/sort natural-compare coll))
(defn sort-by [keyfn coll]
(clojure.core/sort-by keyfn natural-compare coll))
@p-himik
Copy link

p-himik commented Jun 24, 2024

Sure, I don't mind.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment