summaryrefslogtreecommitdiff
path: root/docs/examples.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/examples.rst')
-rw-r--r--docs/examples.rst50
1 files changed, 50 insertions, 0 deletions
diff --git a/docs/examples.rst b/docs/examples.rst
index e44aa1c..04ca632 100644
--- a/docs/examples.rst
+++ b/docs/examples.rst
@@ -245,6 +245,56 @@ sort key so that:
>>> natsorted(b, key=attrgetter('bar'))
[Foo('num2'), Foo('num3'), Foo('num5')]
+.. _unit_sorting:
+
+Accounting for Units When Sorting
++++++++++++++++++++++++++++++++++
+
+:mod:`natsort` does not come with any pre-built mechanism to sort units,
+but you can write your own `key` to do this. Below, I will demonstrate sorting
+imperial lengths (e.g. feet an inches), but of course you can extend this to any
+set of units you need. This example is based on code from
+`this issue <https://github.com/SethMMorton/natsort/issues/100#issuecomment-530659310>`_,
+and uses the function :func:`natsort.numeric_regex_chooser` to build a regular
+expression that will parse numbers in the same manner as :mod:`natsort` itself.
+
+.. code-block:: pycon
+
+ >>> import re
+ >>> import natsort
+ >>>
+ >>> # Define how each unit will be transformed
+ >>> conversion_mapping = {
+ ... "in": 1,
+ ... "inch": 1,
+ ... "inches": 1,
+ ... "ft": 12,
+ ... "feet": 12,
+ ... "foot": 12,
+ ... }
+ >>>
+ >>> # This regular expression searches for numbers and units
+ >>> all_units = "|".join(conversion_mapping.keys())
+ >>> float_re = natsort.numeric_regex_chooser(natsort.FLOAT | natsort.SIGNED)
+ >>> unit_finder = re.compile(r"({})\s*({})".format(float_re, all_units), re.IGNORECASE)
+ >>>
+ >>> def unit_replacer(matchobj):
+ ... """
+ ... Given a regex match object, return a replacement string where units are modified
+ ... """
+ ... number = matchobj.group(1)
+ ... unit = matchobj.group(2)
+ ... new_number = float(number) * conversion_mapping[unit]
+ ... return "{} in".format(new_number)
+ ...
+ >>> # Demo time!
+ >>> data = ['1 ft', '5 in', '10 ft', '2 in']
+ >>> [unit_finder.sub(unit_replacer, x) for x in data]
+ ['12.0 in', '5.0 in', '120.0 in', '2.0 in']
+ >>>
+ >>> natsort.natsorted(data, key=lambda x: unit_finder.sub(unit_replacer, x))
+ ['2 in', '5 in', '1 ft', '10 ft']
+
Generating a Natsort Key
------------------------