Skip to content

Commit

Permalink
docs/howto: use list.{Sort,IsSorted}{,Strings}
Browse files Browse the repository at this point in the history
This adds 2 Commented CUE guides on the matched pairs of
list.Sort/list.IsSorted and list.SortStrings/list.IsSortedStrings.

For *Strings, unusually for a Commented CUE guide, 2 separate examples
are required.

This is because we would ideally show both the happy-path result of all
3 function calls (SortStrings; IsSortedStrings boolean assignment;
IsSortedStrings field validator mode) and also IsSortedStrings field
validator mode when it fails. Only cue-eval-i lets us combine failure
and success messages in one command's output, and it doesn't work in
this situation.

Here's an example txtar that demonstrates the didactic problem with
combining these 2 functions into a single example:

    exec cue eval -i file.cue
    cmp stdout out
    -- file.cue --
    import "list"

    unsorted: ["c", "b", "a"]
    sorted: list.SortStrings(unsorted)

    sorted:   list.IsSortedStrings
    unsorted: list.IsSortedStrings

    testSorted:   list.IsSortedStrings(sorted)
    testUnsorted: list.IsSortedStrings(unsorted)
    -- out --
    unsorted:     _|_ // unsorted: invalid value ["c","b","a"] (does not satisfy list.IsSortedStrings) (and 1 more errors)
    sorted:       _|_ // unsorted: invalid value ["c","b","a"] (does not satisfy list.IsSortedStrings) (and 3 more errors)
    testSorted:   _|_ // unsorted: invalid value ["c","b","a"] (does not satisfy list.IsSortedStrings) (and 7 more errors)
    testUnsorted: _|_ // unsorted: invalid value ["c","b","a"] (does not satisfy list.IsSortedStrings) (and 3 more errors)

I believe this is just an unfortunate side effect of cue-eval-i behaving
as intended, so a cue-lang/cue issue hasn't been raised to improve this
output.

Preview-Path: /docs/howto/use-the-built-in-functions-list-sort-list-issorted/
Preview-Path: /docs/howto/use-the-built-in-functions-list-sortstrings-list-issortedstrings/
Signed-off-by: Jonathan Matthews <[email protected]>
Change-Id: I8938f36f597d3efe88b66b1b78f218db714ab33d
Dispatch-Trailer: {"type":"trybot","CL":1174391,"patchset":13,"ref":"refs/changes/91/1174391/13","targetBranch":"alpha"}
  • Loading branch information
jpluscplusm authored and cueckoo committed Jan 22, 2024
1 parent 731c916 commit da46d96
Show file tree
Hide file tree
Showing 8 changed files with 382 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
---
title: Using the built-in functions "list.Sort" and "list.IsSorted" to sort and test lists
tags:
- commented cue
authors:
- jpluscplusm
toc_hide: true
---

This [Commented CUE]({{< relref "docs/howto#commented-cue-guides" >}})
demonstrates how to use the built-in functions
[`list.Sort`](https://pkg.go.dev/cuelang.org/go/pkg/list#Sort)
to sort lists, and
[`list.IsSorted`](https://pkg.go.dev/cuelang.org/go/pkg/list#IsSorted)
to test that lists are sorted.
Both functions can use either a predefined or custom comparator, as shown
below.

{{{with code "en" "cc1"}}}
#location top bottom

exec cue eval
cmp stdout out
-- file.cue --
package example

import "list"

// When sorting lists that are composed of only numbers or only strings,
// list.Sort may be provided with one of the predefined comparators
// "list.Ascending" or "list.Descending".
numbersAscending: list.Sort([3, 5, 1, 4, 2], list.Ascending)

// Sorting strings alphabetically may also be performed with list.SortStrings
// (see "Related content", below).
// Sorting strings in any other way (including reverse alphabetical order)
// requires list.Sort.
stringsDescending: list.Sort(["aaaaa", "AA", "b", "BBB", "zzzz", "Z"], list.Descending)

// When sorting lists containing other types (or a mixture of types), list.Sort
// must be provided with a custom comparator. The comparator defines how to
// compare the list's elements.
structsCustom: list.Sort([{a: 2}, {a: 3}, {a: 1}], {x: {}, y: {}, less: x.a < y.a})

// The comparator must adhere to the list.Comparer schema (see output, below).
comparatorSchema: list.Comparer

// The comparator can encode any legal CUE comparison between its "x" and
// "y" fields' values. These values might contain any pairing of 2 of the
// list's elements during the sort operation.
// The "less" field must be an expression that is able to compare any 2
// elements from the lists that the comparator will handle. It must evaluate to
// a boolean value that reports if "x" is less than "y".
_stringsCompareLengths: {
x: string
y: string
less: len(x) < len(y)
}

// The comparator does not need to be provided inline - it may be a reference.
stringsLengthAscending: list.Sort(stringsDescending, _stringsCompareLengths)

// list.IsSorted requires a comparator, and reports if the list is sorted
// according to that comparator's definition. The comparator may be a reference.
isSortedAscending: list.IsSorted(stringsLengthAscending, list.Ascending)
isSortedDescending: list.IsSorted(stringsLengthAscending, list.Descending)
isSortedLengthAscending: list.IsSorted(stringsLengthAscending, _stringsCompareLengths)
-- out --
numbersAscending: [1, 2, 3, 4, 5]
stringsDescending: ["zzzz", "b", "aaaaa", "Z", "BBB", "AA"]
structsCustom: [{
a: 1
}, {
a: 2
}, {
a: 3
}]
comparatorSchema: {
T: _
x: _
y: _
less: bool
}
stringsLengthAscending: ["b", "Z", "AA", "BBB", "zzzz", "aaaaa"]
isSortedAscending: false
isSortedDescending: false
isSortedLengthAscending: true
{{{end}}}

## Related content

- Use [`list.SortStrings`]({{< relref
"../use-the-built-in-functions-list-sortstrings-list-issortedstrings"
>}}) to sort lists of strings alphabetically without needing to define a
comparator
- The [`list`](https://pkg.go.dev/cuelang.org/go/pkg/list) built-in package
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package site
{
content: {
docs: {
howto: {
"use-the-built-in-functions-list-sort-list-issorted": {
page: {
cache: {
code: {
cc1: "MW7MKsnCU+dlke06kBs+h9gZy3aeCkenpm48ir/Qu6U="
}
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package site

content: docs: howto: "use-the-built-in-functions-list-sort-list-issorted": {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
title: Using the built-in functions "list.SortStrings" and "list.IsSortedStrings" to sort and test lists of strings
tags:
- commented cue
authors:
- jpluscplusm
toc_hide: true
---

This [Commented CUE]({{< relref "docs/howto#commented-cue-guides" >}})
demonstrates how to use the built-in functions
[`list.SortStrings`](https://pkg.go.dev/cuelang.org/go/pkg/list#SortStrings)
to sort lists of strings, and
[`list.IsSortedStrings`](https://pkg.go.dev/cuelang.org/go/pkg/list#IsSortedStrings)
to test if lists of strings are sorted.

In this first example, `list.IsSortedStrings` is shown returning a boolean
value:

{{{with code "en" "cc1"}}}
#location left right

exec cue eval
cmp stdout out
-- file.cue --
package example

import "list"

unsorted: ["z", "Z", "a", "AAA", "42", "!£$%^&*"]

sorted: list.SortStrings(unsorted)
unsortedTest: list.IsSortedStrings(unsorted)
sortedTest: list.IsSortedStrings(sorted)
-- out --
unsorted: ["z", "Z", "a", "AAA", "42", "!£$%^&*"]
sorted: ["!£$%^&*", "42", "AAA", "Z", "a", "z"]
unsortedTest: false
sortedTest: true
{{{end}}}

`list.IsSortedStrings` can also be used as a validator, directly applied to a
list field.

This second example shows the function producing an evaluation error when
applied to an unsorted list of strings:

{{{with code "en" "cc2"}}}
#location top bottom

! exec cue eval
cmp stderr out
-- file.cue --
package example

import "list"

sorted: ["A", "B", "C"]
unsorted: ["C", "A", "B"]

sorted: list.IsSortedStrings
unsorted: list.IsSortedStrings
-- out --
unsorted: invalid value ["C","A","B"] (does not satisfy list.IsSortedStrings):
./file.cue:6:11
./file.cue:9:11
{{{end}}}

## Related content

- `list.SortStrings` can only sort lists of strings *alphabetically*.
In any other situation, use [`list.Sort`]({{< relref
"../use-the-built-in-functions-list-sort-list-issorted"
>}})
- The [`list`](https://pkg.go.dev/cuelang.org/go/pkg/list) built-in package
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package site
{
content: {
docs: {
howto: {
"use-the-built-in-functions-list-sortstrings-list-issortedstrings": {
page: {
cache: {
code: {
cc1: "MQagsj4jIuVtbz0Uhi82lq8DRIXonIyle8ncQI1nbN4="
cc2: "8sg3oTSJltuzRfQN8n04hVhkGRtziD5np38vBUKU7Vc="
}
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package site

content: docs: howto: "use-the-built-in-functions-list-sortstrings-list-issortedstrings": {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
title: Using the built-in functions "list.Sort" and "list.IsSorted" to sort and test lists
tags:
- commented cue
authors:
- jpluscplusm
toc_hide: true
---

This [Commented CUE]({{< relref "docs/howto#commented-cue-guides" >}})
demonstrates how to use the built-in functions
[`list.Sort`](https://pkg.go.dev/cuelang.org/go/pkg/list#Sort)
to sort lists, and
[`list.IsSorted`](https://pkg.go.dev/cuelang.org/go/pkg/list#IsSorted)
to test that lists are sorted.
Both functions can use either a predefined or custom comparator, as shown
below.

{{< code-tabs >}}
{{< code-tab name="file.cue" language="cue" area="top" >}}
package example

import "list"

// When sorting lists that are composed of only numbers or only strings,
// list.Sort may be provided with one of the predefined comparators
// "list.Ascending" or "list.Descending".
numbersAscending: list.Sort([3, 5, 1, 4, 2], list.Ascending)

// Sorting strings alphabetically may also be performed with list.SortStrings
// (see "Related content", below).
// Sorting strings in any other way (including reverse alphabetical order)
// requires list.Sort.
stringsDescending: list.Sort(["aaaaa", "AA", "b", "BBB", "zzzz", "Z"], list.Descending)

// When sorting lists containing other types (or a mixture of types), list.Sort
// must be provided with a custom comparator. The comparator defines how to
// compare the list's elements.
structsCustom: list.Sort([{a: 2}, {a: 3}, {a: 1}], {x: {}, y: {}, less: x.a < y.a})

// The comparator must adhere to the list.Comparer schema (see output, below).
comparatorSchema: list.Comparer

// The comparator can encode any legal CUE comparison between its "x" and
// "y" fields' values. These values might contain any pairing of 2 of the
// list's elements during the sort operation.
// The "less" field must be an expression that is able to compare any 2
// elements from the lists that the comparator will handle. It must evaluate to
// a boolean value that reports if "x" is less than "y".
_stringsCompareLengths: {
x: string
y: string
less: len(x) < len(y)
}

// The comparator does not need to be provided inline - it may be a reference.
stringsLengthAscending: list.Sort(stringsDescending, _stringsCompareLengths)

// list.IsSorted requires a comparator, and reports if the list is sorted
// according to that comparator's definition. The comparator may be a reference.
isSortedAscending: list.IsSorted(stringsLengthAscending, list.Ascending)
isSortedDescending: list.IsSorted(stringsLengthAscending, list.Descending)
isSortedLengthAscending: list.IsSorted(stringsLengthAscending, _stringsCompareLengths)
{{< /code-tab >}}
{{< code-tab name="TERMINAL" language="" type="terminal" area="bottom" >}}
$ cue eval
numbersAscending: [1, 2, 3, 4, 5]
stringsDescending: ["zzzz", "b", "aaaaa", "Z", "BBB", "AA"]
structsCustom: [{
a: 1
}, {
a: 2
}, {
a: 3
}]
comparatorSchema: {
T: _
x: _
y: _
less: bool
}
stringsLengthAscending: ["b", "Z", "AA", "BBB", "zzzz", "aaaaa"]
isSortedAscending: false
isSortedDescending: false
isSortedLengthAscending: true
{{< /code-tab >}}
{{< /code-tabs >}}

## Related content

- Use [`list.SortStrings`]({{< relref
"../use-the-built-in-functions-list-sortstrings-list-issortedstrings"
>}}) to sort lists of strings alphabetically without needing to define a
comparator
- The [`list`](https://pkg.go.dev/cuelang.org/go/pkg/list) built-in package
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
title: Using the built-in functions "list.SortStrings" and "list.IsSortedStrings" to sort and test lists of strings
tags:
- commented cue
authors:
- jpluscplusm
toc_hide: true
---

This [Commented CUE]({{< relref "docs/howto#commented-cue-guides" >}})
demonstrates how to use the built-in functions
[`list.SortStrings`](https://pkg.go.dev/cuelang.org/go/pkg/list#SortStrings)
to sort lists of strings, and
[`list.IsSortedStrings`](https://pkg.go.dev/cuelang.org/go/pkg/list#IsSortedStrings)
to test if lists of strings are sorted.

In this first example, `list.IsSortedStrings` is shown returning a boolean
value:

{{< code-tabs >}}
{{< code-tab name="file.cue" language="cue" area="left" >}}
package example

import "list"

unsorted: ["z", "Z", "a", "AAA", "42", "!£$%^&*"]

sorted: list.SortStrings(unsorted)
unsortedTest: list.IsSortedStrings(unsorted)
sortedTest: list.IsSortedStrings(sorted)
{{< /code-tab >}}
{{< code-tab name="TERMINAL" language="" type="terminal" area="right" >}}
$ cue eval
unsorted: ["z", "Z", "a", "AAA", "42", "!£$%^&*"]
sorted: ["!£$%^&*", "42", "AAA", "Z", "a", "z"]
unsortedTest: false
sortedTest: true
{{< /code-tab >}}
{{< /code-tabs >}}

`list.IsSortedStrings` can also be used as a validator, directly applied to a
list field.

This second example shows the function producing an evaluation error when
applied to an unsorted list of strings:

{{< code-tabs >}}
{{< code-tab name="file.cue" language="cue" area="top" >}}
package example

import "list"

sorted: ["A", "B", "C"]
unsorted: ["C", "A", "B"]

sorted: list.IsSortedStrings
unsorted: list.IsSortedStrings
{{< /code-tab >}}
{{< code-tab name="TERMINAL" language="" type="terminal" area="bottom" >}}
$ cue eval
unsorted: invalid value ["C","A","B"] (does not satisfy list.IsSortedStrings):
./file.cue:6:11
./file.cue:9:11
{{< /code-tab >}}
{{< /code-tabs >}}

## Related content

- `list.SortStrings` can only sort lists of strings *alphabetically*.
In any other situation, use [`list.Sort`]({{< relref
"../use-the-built-in-functions-list-sort-list-issorted"
>}})
- The [`list`](https://pkg.go.dev/cuelang.org/go/pkg/list) built-in package

0 comments on commit da46d96

Please sign in to comment.