Skip to content

Commit 896ed4e

Browse files
committed
Add better strict sorting variants
1 parent b2dfbd2 commit 896ed4e

File tree

1 file changed

+39
-12
lines changed

1 file changed

+39
-12
lines changed

book/sorting.md

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -259,27 +259,54 @@ Here's an example of a custom sort which couldn't be trivially written as a key
259259

260260
### Strict sort
261261

262-
Custom sort closures also provide a simple way to sort data while enforcing type homogeneity. This takes advantage of [operators requiring compatible data types](operators.html#types):
262+
Custom sort closures also provides a simple way to sort data while ensuring only types with well-defined comparisons are sorted together. This takes advantage of [operators requiring compatible data types](operators.html#types):
263263

264264
```nu
265-
> let data = ["hello" 4 9 2 1 "foobar" 8 6]
266-
> $data | sort-by -c {|a, b| $a < $b}
265+
> let compatible = [8 3.2 null 58 2]
266+
> let incompatible = ["hello" 4 9 2 1 "meow" 8 6]
267+
> $compatible | sort-by -c {|a, b| $a < $b | default ($a != null) }
268+
╭───┬──────╮
269+
│ 0 │ 2 │
270+
│ 1 │ 3.20 │
271+
│ 2 │ 8 │
272+
│ 3 │ 58 │
273+
│ 4 │ │
274+
╰───┴──────╯
275+
> $incompatible | sort-by -c {|a, b| $a < $b | default ($a != null) }
267276
Error: nu::shell::type_mismatch
268277
269278
× Type mismatch during operation.
270-
╭─[entry #173:1:28]
271-
1 │ $data | sort-by -c {|a, b| $a < $b}
272-
· ─┬ ┬ ─┬
273-
· │ │ ╰── string
274-
· │ ╰── type mismatch for operator
275-
· ╰── int
279+
╭─[entry #26:1:36]
280+
1 │ $incompatible | sort-by -c {|a, b| $a < $b | default ($a != null) }
281+
· ─┬ ┬ ─┬
282+
· │ │ ╰── string
283+
· │ ╰── type mismatch for operator
284+
· ╰── int
276285
╰────
277286
278287
```
279288

280-
::: warning
281-
This does not currently work with `null` values due to comparison between any value and `null` returning `null`.
282-
:::
289+
Special handling is required for `null` values, since comparison between any value and `null` returns `null`. To instead reject `null` values, try the following:
290+
291+
```nu
292+
> let baddata = [8 3.2 null 58 2]
293+
> let strict = {|a, b|
294+
match [$a, $b] {
295+
[null, _] => (error make {msg: "Attempt to sort null"}),
296+
[_, null] => (error make {msg: "Attempt to sort null"}),
297+
_ => ($a < $b)
298+
}
299+
}
300+
> $baddata | sort-by -c $strict
301+
Error: × Attempt to sort null
302+
╭─[entry #3:4:21]
303+
3 │ match [$a, $b] {
304+
4 │ [null, _] => (error make {msg: "Attempt to sort null"}),
305+
· ─────┬────
306+
· ╰── originates from here
307+
5 │ [_, null] => (error make {msg: "Attempt to sort null"}),
308+
╰────
309+
```
283310

284311
## Special sorts
285312

0 commit comments

Comments
 (0)