Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type testCase[C any, V any] struct {
want2 any
want3 any
want4 any
want5 any
got1 any
got2 any
got3 any
Expand Down
2 changes: 1 addition & 1 deletion definitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ type Mutable[V any] interface {
Clear()

// RemoveMatching removes all elements that match the given predicate.
RemoveMatching(predicate Predicate[V]) // TODO: return count of removed items
RemoveMatching(predicate Predicate[V]) (count int)
}

// IndexedMutable is a mutable collection that can be modified based on the indexes.
Expand Down
9 changes: 6 additions & 3 deletions functions_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,20 @@ func sliceRemoveAt[V any](s []V, i int) (removed V, newSLice []V, err error) {
}

// sliceRemoveMatching removes all elements for which the predicate returns true.
func sliceRemoveMatching[V any](s []V, predicate Predicate[V]) []V {
func sliceRemoveMatching[V any](s []V, predicate Predicate[V]) ([]V, int) {
removed := 0
newS := make([]V, 0, len(s))
for _, v := range s {
if !predicate(v) {
newS = append(newS, v)
} else {
removed++
}
}

if len(newS) == 0 {
return []V(nil)
return []V(nil), removed
}

return newS
return newS, removed
}
5 changes: 4 additions & 1 deletion map.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func (c *comfyMap[K, V]) RemoveMany(keys []K) {
c.removeMany(keys)
}

func (c *comfyMap[K, V]) RemoveMatching(predicate Predicate[Pair[K, V]]) {
func (c *comfyMap[K, V]) RemoveMatching(predicate Predicate[Pair[K, V]]) (count int) {
newS := []Pair[K, V](nil)
newM := make(map[K]Pair[K, V])
newKP := make(map[K]int)
Expand All @@ -160,12 +160,15 @@ func (c *comfyMap[K, V]) RemoveMatching(predicate Predicate[Pair[K, V]]) {
newM[pair.Key()] = pair
newKP[pair.Key()] = idx
idx++
} else {
count++
}
}

c.s = newS
c.m = newM
c.kp = newKP
return count
}

func (c *comfyMap[K, V]) Reverse() {
Expand Down
23 changes: 22 additions & 1 deletion map_cases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1449,6 +1449,7 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
want2: map[int]int{},
want3: map[int]int{},
want4: map[int]int{},
want5: 0,
},
{
name: "RemoveMatching() on one-item collection, found",
Expand All @@ -1458,6 +1459,7 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
want2: map[int]int{},
want3: map[int]int{},
want4: map[int]int{},
want5: 1,
},
{
name: "RemoveMatching() on one-item collection, not found",
Expand All @@ -1467,6 +1469,7 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
want2: map[int]int{1: 111},
want3: map[int]int{1: 0},
want4: map[int]int{111: 1},
want5: 0,
},
{
name: "RemoveMatching() on three-item collection, found all",
Expand All @@ -1476,6 +1479,7 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
want2: map[int]int{},
want3: map[int]int{},
want4: map[int]int{},
want5: 3,
},
{
name: "RemoveMatching() on three-item collection, found none",
Expand All @@ -1485,6 +1489,7 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
want2: map[int]int{1: 111, 2: 222, 3: 333},
want3: map[int]int{1: 0, 2: 1, 3: 2},
want4: map[int]int{111: 1, 222: 1, 333: 1},
want5: 0,
},
{
name: "RemoveMatching() on three-item collection, found first",
Expand All @@ -1494,6 +1499,7 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
want2: map[int]int{2: 222, 3: 333},
want3: map[int]int{2: 0, 3: 1},
want4: map[int]int{222: 1, 333: 1},
want5: 1,
},
{
name: "RemoveMatching() on three-item collection, found middle",
Expand All @@ -1503,6 +1509,7 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
want2: map[int]int{1: 111, 3: 333},
want3: map[int]int{1: 0, 3: 1},
want4: map[int]int{111: 1, 333: 1},
want5: 1,
},
{
name: "RemoveMatching() on three-item collection, found last",
Expand All @@ -1512,6 +1519,17 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
want2: map[int]int{1: 111, 2: 222},
want3: map[int]int{1: 0, 2: 1},
want4: map[int]int{111: 1, 222: 1},
want5: 1,
},
{
name: "RemoveMatching() on three-item collection, found even",
coll: builder.Three(),
args: baseMapIntArgs{predicate: func(p Pair[int, int]) bool { return p.Val()%2 != 0 }},
want1: []Pair[int, int]{NewPair(2, 222)},
want2: map[int]int{2: 222},
want3: map[int]int{2: 0},
want4: map[int]int{222: 1},
want5: 2,
},
}
}
Expand All @@ -1520,7 +1538,7 @@ func testMapRemoveMatching(t *testing.T, builder baseMapCollIntBuilder) {
cases := getMapRemoveMatchingCases(builder)
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
tt.coll.RemoveMatching(tt.args.predicate)
count := tt.coll.RemoveMatching(tt.args.predicate)
actualSlice := builder.extractUnderlyingSlice(tt.coll)
actualMap := builder.extractUnderlyingMap(tt.coll)
actualKP := builder.extractUnderlyingKp(tt.coll)
Expand All @@ -1539,6 +1557,9 @@ func testMapRemoveMatching(t *testing.T, builder baseMapCollIntBuilder) {
t.Errorf("RemoveMatching() did not remove correctly from values counter")
}
}
if count != tt.want5 {
t.Errorf("RemoveMatching() returned wrong count: %v, but wanted = %v", count, tt.want5)
}
})
}
}
Expand Down
5 changes: 4 additions & 1 deletion mapcmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ func (c *comfyCmpMap[K, V]) RemoveMany(keys []K) {
c.removeMany(keys)
}

func (c *comfyCmpMap[K, V]) RemoveMatching(predicate Predicate[Pair[K, V]]) {
func (c *comfyCmpMap[K, V]) RemoveMatching(predicate Predicate[Pair[K, V]]) (count int) {
newS := []Pair[K, V](nil)
newM := make(map[K]Pair[K, V])
newKP := make(map[K]int)
Expand All @@ -204,13 +204,16 @@ func (c *comfyCmpMap[K, V]) RemoveMatching(predicate Predicate[Pair[K, V]]) {
newKP[pair.Key()] = idx
newVC.Increment(pair.Val())
idx++
} else {
count++
}
}

c.s = newS
c.m = newM
c.kp = newKP
c.vc = newVC
return count
}

func (c *comfyCmpMap[K, V]) RemoveValues(v V) {
Expand Down
12 changes: 11 additions & 1 deletion mutable_cases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,48 +111,55 @@ func getRemoveMatchingCases(builder mutableIntTestBuilder) []mutableIntTestCase
args: mutableIntTestArgs{predicate: func(v int) bool { return true }},
want1: []int(nil),
want2: map[int]int{},
want3: 0,
},
{
name: "RemoveMatching() on one-item collection",
coll: builder.One(),
args: mutableIntTestArgs{predicate: func(v int) bool { return v == 111 }},
want1: []int(nil),
want2: map[int]int{},
want3: 1,
},
{
name: "RemoveMatching() on three-item collection",
coll: builder.Three(),
args: mutableIntTestArgs{predicate: func(v int) bool { return v == 222 }},
want1: []int{111, 333},
want2: map[int]int{111: 1, 333: 1},
want3: 1,
},
{
name: "RemoveMatching() on three-item collection, all false",
coll: builder.Three(),
args: mutableIntTestArgs{predicate: func(v int) bool { return false }},
want1: []int{111, 222, 333},
want2: map[int]int{111: 1, 222: 1, 333: 1},
want3: 0,
},
{
name: "RemoveMatching() on three-item collection, all true",
coll: builder.Three(),
args: mutableIntTestArgs{predicate: func(v int) bool { return true }},
want1: []int(nil),
want2: map[int]int{},
want3: 3,
},
{
name: "RemoveMatching() on three-item collection, some mod 2",
coll: builder.Three(),
args: mutableIntTestArgs{predicate: func(v int) bool { return v%2 == 0 }},
want1: []int{111, 333},
want2: map[int]int{111: 1, 333: 1},
want3: 1,
},
{
name: "RemoveMatching() on three-item collection, some not mod 2",
coll: builder.Three(),
args: mutableIntTestArgs{predicate: func(v int) bool { return v%2 != 0 }},
want1: []int{222},
want2: map[int]int{222: 1},
want3: 2,
},
}
}
Expand All @@ -161,7 +168,7 @@ func testRemoveMatching(t *testing.T, builder mutableIntTestBuilder) {
cases := getRemoveMatchingCases(builder)
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
tt.coll.RemoveMatching(tt.args.predicate)
count := tt.coll.RemoveMatching(tt.args.predicate)

actualSlice := builder.extractUnderlyingSlice(tt.coll)
actualVC := builder.extractUnderlyingValsCount(tt.coll)
Expand All @@ -172,6 +179,9 @@ func testRemoveMatching(t *testing.T, builder mutableIntTestBuilder) {
if actualVC != nil && !reflect.DeepEqual(actualVC, tt.want2) {
t.Errorf("RemoveMatching() did not remove correctly from values counter")
}
if count != tt.want3 {
t.Errorf("RemoveMatching() returned wrong count: %v, but wanted = %v", count, tt.want3)
}
})
}
}
5 changes: 3 additions & 2 deletions sequence.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ func (c *comfySeq[V]) RemoveAt(i int) (removed V, err error) {
return removed, nil
}

func (c *comfySeq[V]) RemoveMatching(predicate Predicate[V]) {
c.s = sliceRemoveMatching(c.s, predicate)
func (c *comfySeq[V]) RemoveMatching(predicate Predicate[V]) (count int) {
c.s, count = sliceRemoveMatching(c.s, predicate)
return count
}

func (c *comfySeq[V]) Reverse() {
Expand Down
5 changes: 4 additions & 1 deletion sequencecmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,17 +140,20 @@ func (c *comfyCmpSeq[V]) RemoveAt(i int) (removed V, err error) {
return removed, nil
}

func (c *comfyCmpSeq[V]) RemoveMatching(predicate Predicate[V]) {
func (c *comfyCmpSeq[V]) RemoveMatching(predicate Predicate[V]) (count int) {
newS := []V(nil)
newVC := newValuesCounter[V]()
for _, v := range c.s {
if !predicate(v) {
newS = append(newS, v)
newVC.Increment(v)
} else {
count++
}
}
c.s = newS
c.vc = newVC
return count
}

func (c *comfyCmpSeq[V]) RemoveValues(v V) {
Expand Down
Loading