Skip to content

Commit

Permalink
Merge branch 'master' of github.com:gozelle/async
Browse files Browse the repository at this point in the history
  • Loading branch information
koyeo committed Aug 29, 2023
2 parents f69c0b4 + 953cc66 commit a0f672b
Show file tree
Hide file tree
Showing 15 changed files with 868 additions and 54 deletions.
3 changes: 3 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

echo "this is from pre commit script"
31 changes: 31 additions & 0 deletions collection/slices.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package collection

// UniqueKeys Slices Get a unique slices
// T => slice item type
// K => slice item filter key type
func UniqueKeys[T any, K comparable](items []T, fn func(item T) K) []K {
r := make([]K, 0)
m := map[K]struct{}{}
for _, v := range items {
k := fn(v)
if _, ok := m[k]; !ok {
m[k] = struct{}{}
r = append(r, k)
}
}
return r
}

// UniqueMap convert slice to a map by unique key
// T => slice item type
// K => slice item filter key type
func UniqueMap[T any, K comparable](items []T, fn func(item T) (K, T)) map[K]T {
m := map[K]T{}
for _, v := range items {
k, vv := fn(v)
if _, ok := m[k]; !ok {
m[k] = vv
}
}
return m
}
55 changes: 55 additions & 0 deletions collection/slices_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package collection

import "testing"

func TestUniqueKeys(t *testing.T) {
a := []string{"a", "b", "c", "d", "d", "c", "a"}
b := UniqueKeys[string, string](a, func(item string) (key string) {
key = item
return
})
t.Log(b)

type I struct {
Group string
User string
}

items := []I{
{Group: "a", User: "tom"},
{Group: "a", User: "bob"},
{Group: "b", User: "jack"},
}

ii := UniqueKeys[I, string](items, func(item I) (key string) {
return item.Group
})

t.Log(ii)
}

func TestUniqueMap(t *testing.T) {
a := []string{"a", "b", "c", "d", "d", "c", "a"}
b := UniqueKeys[string, string](a, func(item string) (key string) {
key = item
return
})
t.Log(b)

type I struct {
Group string
User string
}

items := []I{
{Group: "a", User: "tom"},
{Group: "a", User: "bob"},
{Group: "b", User: "jack"},
}

ii := UniqueMap[I, string](items, func(item I) (key string, v I) {
return item.Group, item
})

t.Log(ii)
}
53 changes: 53 additions & 0 deletions collection/sort.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package collection

import (
"github.com/gozelle/async/generics"
"sort"
)

var _ sort.Interface = (*sorter[any])(nil)

type sorter[T any] struct {
list []T
less func(a, b T) bool
}

func (s sorter[T]) Len() int {
return len(s.list)
}

func (s sorter[T]) Less(i, j int) bool {
return s.less(s.list[i], s.list[j])
}

func (s sorter[T]) Swap(i, j int) {
s.list[i], s.list[j] = s.list[j], s.list[i]
}

func Sort[T any](items []T, less func(a, b T) bool) {
s := sorter[T]{
list: items,
less: less,
}
sort.Sort(s)
}

func SortAsc[T any, K generics.Ordered](items []T, key func(item T) K) {
s := &sorter[T]{
list: items,
less: func(a, b T) bool {
return key(a) < key(b)
},
}
sort.Sort(s)
}

func SortDesc[T any, K generics.Ordered](items []T, key func(item T) K) {
s := &sorter[T]{
list: items,
less: func(a, b T) bool {
return key(a) > key(b)
},
}
sort.Sort(s)
}
45 changes: 45 additions & 0 deletions collection/sort_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package collection

import "testing"

type User struct {
Id int
Name string
}

func TestSort(t *testing.T) {
list := []int{1, 3, 4, 2, 5}
strs := []string{"a", "c", "d", "e", "b"}

Sort(list, func(a, b int) bool {
return a > b
})
t.Log(list)

Sort(strs, func(a, b string) bool {
return a < b
})
t.Log(strs)
}

func TestSortAsc(t *testing.T) {
list := []int{1, 3, 4, 2, 5}
SortAsc(list, func(item int) int {
return item
})
t.Log(list)

users := []User{
{Id: 1, Name: "tom"},
{Id: 2, Name: "jack"},
{Id: 3, Name: "jack"},
}
SortAsc(users, func(item User) int {
return item.Id
})
t.Log(users)
SortDesc(users, func(item User) int {
return item.Id
})
t.Log(users)
}
50 changes: 50 additions & 0 deletions generics/constraints.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package constraints defines a set of useful constraints to be used
// with type parameters.
package generics

// Signed is a constraint that permits any signed integer type.
// If future releases of Go add new predeclared signed integer types,
// this constraint will be modified to include them.
type Signed interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}

// Unsigned is a constraint that permits any unsigned integer type.
// If future releases of Go add new predeclared unsigned integer types,
// this constraint will be modified to include them.
type Unsigned interface {
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}

// Integer is a constraint that permits any integer type.
// If future releases of Go add new predeclared integer types,
// this constraint will be modified to include them.
type Integer interface {
Signed | Unsigned
}

// Float is a constraint that permits any floating-point type.
// If future releases of Go add new predeclared floating-point types,
// this constraint will be modified to include them.
type Float interface {
~float32 | ~float64
}

// Complex is a constraint that permits any complex numeric type.
// If future releases of Go add new predeclared complex numeric types,
// this constraint will be modified to include them.
type Complex interface {
~complex64 | ~complex128
}

// Ordered is a constraint that permits any ordered type: any type
// that supports the operators < <= >= >.
// If future releases of Go add new ordered types,
// this constraint will be modified to include them.
type Ordered interface {
Integer | Float | ~string
}
Loading

0 comments on commit a0f672b

Please sign in to comment.