Skip to content

Commit

Permalink
add SliceWrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
liyue201 committed Apr 3, 2020
1 parent ff779af commit 86d7d9d
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 0 deletions.
73 changes: 73 additions & 0 deletions ds/slice/slice_wrapper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package slice

import "reflect"

//SliceWrapper wraps a slice in order to provide functions related to iterators
type SliceWrapper struct {
slice interface{}
sliceValue reflect.Value
itemType reflect.Type
}

// New creates a SliceWrapper
func NewSliceWrapper(slice interface{}, itemType reflect.Type) *SliceWrapper {
return &SliceWrapper{
slice: slice,
sliceValue: reflect.ValueOf(slice),
itemType: itemType,
}
}

func (s *SliceWrapper) Attach(newSlice interface{}) {
if reflect.ValueOf(newSlice).Kind() == s.sliceValue.Kind() {
s.slice = newSlice
s.sliceValue = reflect.ValueOf(newSlice)
}
}

// Len returns the length of s
func (s *SliceWrapper) Len() int {
return s.sliceValue.Len()
}

// At returns the value at position
func (s *SliceWrapper) At(position int) interface{} {
if position < 0 || position >= s.Len() {
return nil
}
return s.sliceValue.Index(position).Interface()
}

// Set sets value at position
func (s *SliceWrapper) Set(position int, val interface{}) {
if position < 0 || position >= s.Len() {
return
}
s.sliceValue.Index(position).Set(reflect.ValueOf(val))
}

// Begin returns the first iterator of s
func (s *SliceWrapper) Begin() *SliceIterator {
return s.First()
}

// End returns the end iterator of s
func (s *SliceWrapper) End() *SliceIterator {
return &SliceIterator{s: s,
position: s.Len(),
}
}

// First returns the first iterator of s
func (s *SliceWrapper) First() *SliceIterator {
return &SliceIterator{s: s,
position: 0,
}
}

// Last returns the last iterator of s
func (s *SliceWrapper) Last() *SliceIterator {
return &SliceIterator{s: s,
position: s.Len(),
}
}
52 changes: 52 additions & 0 deletions ds/slice/slice_wrapper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package slice

import (
"github.com/liyue201/gostl/algorithm/sort"
"github.com/stretchr/testify/assert"
"reflect"
"testing"
)

func TestSliceWrapper(t *testing.T) {
type User struct {
age int
name string
}

a := make([]*User, 0)
a = append(a, &User{age: 2, name: "zzz"})
a = append(a, &User{age: 5, name: "nnn"})
a = append(a, &User{age: 2, name: "aaa"})

sw := NewSliceWrapper(a, reflect.TypeOf(&User{}))

assert.Equal(t, 3, sw.Len())

sort.Sort(sw.Begin(), sw.End(), func(a, b interface{}) int {
ua := a.(*User)
ub := b.(*User)
if ua.age < ub.age {
return -1
}
if ua.age > ub.age {
return 1
}
if ua.name < ub.name {
return -1
}
if ua.name > ub.name {
return 1
}
return 0
})
for i := range a {
t.Logf("%+v\n", a[i])
assert.Equal(t, a[i], sw.At(i))
if i > 0 {
assert.LessOrEqual(t, a[i-1].age, a[i].age)
if a[i-1].age == a[i].age {
assert.LessOrEqual(t, a[i-1].name, a[i].name)
}
}
}
}

0 comments on commit 86d7d9d

Please sign in to comment.