Skip to content

Commit

Permalink
uniq
Browse files Browse the repository at this point in the history
  • Loading branch information
bradenhilton committed May 19, 2024
1 parent 5d26c4e commit 0e91528
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 1 deletion.
10 changes: 10 additions & 0 deletions docs/templatefuncs.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,13 @@ FOOBAR
foobar
```

## `uniq` *list*

`uniq` returns a new list containing only unique elements in *list*.

```text
{{ list 1 2 1 3 3 2 1 2 | uniq }}
[1 2 3]
```
18 changes: 17 additions & 1 deletion templatefuncs.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func NewFuncMap() template.FuncMap {
"toString": toStringTemplateFunc,
"toUpper": eachString(strings.ToUpper),
"trimSpace": eachString(strings.TrimSpace),
"uniq": uniqTemplateFunc,
}
}

Expand Down Expand Up @@ -277,7 +278,22 @@ func toStringTemplateFunc(arg any) string {
}
}

// convertAndSortSlice converts a `[]any` to a `[]T` and sorts it.
// uniqTemplateFunc is the core implementation of the `uniq` template function.
func uniqTemplateFunc(list []any) []any {
seen := make(map[any]struct{})
result := []any{}

for _, v := range list {
if _, ok := seen[v]; !ok {
result = append(result, v)
seen[v] = struct{}{}
}
}

return result
}

// convertAndSortSlice creates a `[]T` copy of its input and sorts it.
func convertAndSortSlice[T cmp.Ordered](slice []any) []T {
l := make([]T, len(slice))
for i, elem := range slice {
Expand Down
4 changes: 4 additions & 0 deletions templatefuncs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ func TestFuncMap(t *testing.T) {
template: `{{ trimSpace " a " }}`,
expected: "a",
},
{
template: `{{ list 1 2 1 3 3 2 1 2 | uniq }}`,
expected: "[1 2 3]",
},
} {
t.Run(strconv.Itoa(i), func(t *testing.T) {
tmpl, err := template.New("").Funcs(funcMap).Parse(tc.template)
Expand Down

0 comments on commit 0e91528

Please sign in to comment.