Skip to content

Commit dddf629

Browse files
committed
Add uniq() function
1 parent da04c55 commit dddf629

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

builtin/builtin.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,57 @@ var Builtins = []*Function{
830830
}
831831
},
832832
},
833+
834+
{
835+
Name: "uniq",
836+
Func: func(args ...any) (any, error) {
837+
if len(args) != 1 {
838+
return nil, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
839+
}
840+
841+
v := reflect.ValueOf(deref.Deref(args[0]))
842+
if v.Kind() != reflect.Array && v.Kind() != reflect.Slice {
843+
return nil, fmt.Errorf("cannot uniq %s", v.Kind())
844+
}
845+
846+
size := v.Len()
847+
ret := []any{}
848+
849+
eq := func(i int) bool {
850+
for _, r := range ret {
851+
if runtime.Equal(v.Index(i).Interface(), r) {
852+
return true
853+
}
854+
}
855+
856+
return false
857+
}
858+
859+
for i := 0; i < size; i += 1 {
860+
if eq(i) {
861+
continue
862+
}
863+
864+
ret = append(ret, v.Index(i).Interface())
865+
}
866+
867+
return ret, nil
868+
},
869+
870+
Validate: func(args []reflect.Type) (reflect.Type, error) {
871+
if len(args) != 1 {
872+
return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
873+
}
874+
875+
switch kind(args[0]) {
876+
case reflect.Interface, reflect.Slice, reflect.Array:
877+
return arrayType, nil
878+
default:
879+
return anyType, fmt.Errorf("cannot uniq %s", args[0])
880+
}
881+
},
882+
},
883+
833884
{
834885
Name: "concat",
835886
Safe: func(args ...any) (any, uint, error) {

builtin/builtin_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ func TestBuiltin(t *testing.T) {
155155
{`flatten([["a", "b"], [1, 2]])`, []any{"a", "b", 1, 2}},
156156
{`flatten([["a", "b"], [1, 2, [3, 4]]])`, []any{"a", "b", 1, 2, 3, 4}},
157157
{`flatten([["a", "b"], [1, 2, [3, [[[["c", "d"], "e"]]], 4]]])`, []any{"a", "b", 1, 2, 3, "c", "d", "e", 4}},
158+
{`uniq([1, 15, "a", 2, 3, 5, 2, "a", 2, "b"])`, []any{1, 15, "a", 2, 3, 5, "b"}},
159+
{`uniq([[1, 2], "a", 2, 3, [1, 2], [1, 3]])`, []any{[]any{1, 2}, "a", 2, 3, []any{1, 3}}},
158160
}
159161

160162
for _, test := range tests {

0 commit comments

Comments
 (0)