Skip to content

Commit 0158754

Browse files
authored
#13 - RemoveMatching methods return the number of removed items (#31)
* #13 - RemoveMatching methods return the number of removed items * #13 - Fix test to check the removed items count
1 parent 717d538 commit 0158754

File tree

9 files changed

+56
-11
lines changed

9 files changed

+56
-11
lines changed

common_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type testCase[C any, V any] struct {
3434
want2 any
3535
want3 any
3636
want4 any
37+
want5 any
3738
got1 any
3839
got2 any
3940
got3 any

definitions.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ type Mutable[V any] interface {
8989
Clear()
9090

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

9595
// IndexedMutable is a mutable collection that can be modified based on the indexes.

functions_internal.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,20 @@ func sliceRemoveAt[V any](s []V, i int) (removed V, newSLice []V, err error) {
5858
}
5959

6060
// sliceRemoveMatching removes all elements for which the predicate returns true.
61-
func sliceRemoveMatching[V any](s []V, predicate Predicate[V]) []V {
61+
func sliceRemoveMatching[V any](s []V, predicate Predicate[V]) ([]V, int) {
62+
removed := 0
6263
newS := make([]V, 0, len(s))
6364
for _, v := range s {
6465
if !predicate(v) {
6566
newS = append(newS, v)
67+
} else {
68+
removed++
6669
}
6770
}
6871

6972
if len(newS) == 0 {
70-
return []V(nil)
73+
return []V(nil), removed
7174
}
7275

73-
return newS
76+
return newS, removed
7477
}

map.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ func (c *comfyMap[K, V]) RemoveMany(keys []K) {
148148
c.removeMany(keys)
149149
}
150150

151-
func (c *comfyMap[K, V]) RemoveMatching(predicate Predicate[Pair[K, V]]) {
151+
func (c *comfyMap[K, V]) RemoveMatching(predicate Predicate[Pair[K, V]]) (count int) {
152152
newS := []Pair[K, V](nil)
153153
newM := make(map[K]Pair[K, V])
154154
newKP := make(map[K]int)
@@ -160,12 +160,15 @@ func (c *comfyMap[K, V]) RemoveMatching(predicate Predicate[Pair[K, V]]) {
160160
newM[pair.Key()] = pair
161161
newKP[pair.Key()] = idx
162162
idx++
163+
} else {
164+
count++
163165
}
164166
}
165167

166168
c.s = newS
167169
c.m = newM
168170
c.kp = newKP
171+
return count
169172
}
170173

171174
func (c *comfyMap[K, V]) Reverse() {

map_cases_test.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1449,6 +1449,7 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
14491449
want2: map[int]int{},
14501450
want3: map[int]int{},
14511451
want4: map[int]int{},
1452+
want5: 0,
14521453
},
14531454
{
14541455
name: "RemoveMatching() on one-item collection, found",
@@ -1458,6 +1459,7 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
14581459
want2: map[int]int{},
14591460
want3: map[int]int{},
14601461
want4: map[int]int{},
1462+
want5: 1,
14611463
},
14621464
{
14631465
name: "RemoveMatching() on one-item collection, not found",
@@ -1467,6 +1469,7 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
14671469
want2: map[int]int{1: 111},
14681470
want3: map[int]int{1: 0},
14691471
want4: map[int]int{111: 1},
1472+
want5: 0,
14701473
},
14711474
{
14721475
name: "RemoveMatching() on three-item collection, found all",
@@ -1476,6 +1479,7 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
14761479
want2: map[int]int{},
14771480
want3: map[int]int{},
14781481
want4: map[int]int{},
1482+
want5: 3,
14791483
},
14801484
{
14811485
name: "RemoveMatching() on three-item collection, found none",
@@ -1485,6 +1489,7 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
14851489
want2: map[int]int{1: 111, 2: 222, 3: 333},
14861490
want3: map[int]int{1: 0, 2: 1, 3: 2},
14871491
want4: map[int]int{111: 1, 222: 1, 333: 1},
1492+
want5: 0,
14881493
},
14891494
{
14901495
name: "RemoveMatching() on three-item collection, found first",
@@ -1494,6 +1499,7 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
14941499
want2: map[int]int{2: 222, 3: 333},
14951500
want3: map[int]int{2: 0, 3: 1},
14961501
want4: map[int]int{222: 1, 333: 1},
1502+
want5: 1,
14971503
},
14981504
{
14991505
name: "RemoveMatching() on three-item collection, found middle",
@@ -1503,6 +1509,7 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
15031509
want2: map[int]int{1: 111, 3: 333},
15041510
want3: map[int]int{1: 0, 3: 1},
15051511
want4: map[int]int{111: 1, 333: 1},
1512+
want5: 1,
15061513
},
15071514
{
15081515
name: "RemoveMatching() on three-item collection, found last",
@@ -1512,6 +1519,17 @@ func getMapRemoveMatchingCases(builder baseMapCollIntBuilder) []baseMapTestCase
15121519
want2: map[int]int{1: 111, 2: 222},
15131520
want3: map[int]int{1: 0, 2: 1},
15141521
want4: map[int]int{111: 1, 222: 1},
1522+
want5: 1,
1523+
},
1524+
{
1525+
name: "RemoveMatching() on three-item collection, found even",
1526+
coll: builder.Three(),
1527+
args: baseMapIntArgs{predicate: func(p Pair[int, int]) bool { return p.Val()%2 != 0 }},
1528+
want1: []Pair[int, int]{NewPair(2, 222)},
1529+
want2: map[int]int{2: 222},
1530+
want3: map[int]int{2: 0},
1531+
want4: map[int]int{222: 1},
1532+
want5: 2,
15151533
},
15161534
}
15171535
}
@@ -1520,7 +1538,7 @@ func testMapRemoveMatching(t *testing.T, builder baseMapCollIntBuilder) {
15201538
cases := getMapRemoveMatchingCases(builder)
15211539
for _, tt := range cases {
15221540
t.Run(tt.name, func(t *testing.T) {
1523-
tt.coll.RemoveMatching(tt.args.predicate)
1541+
count := tt.coll.RemoveMatching(tt.args.predicate)
15241542
actualSlice := builder.extractUnderlyingSlice(tt.coll)
15251543
actualMap := builder.extractUnderlyingMap(tt.coll)
15261544
actualKP := builder.extractUnderlyingKp(tt.coll)
@@ -1539,6 +1557,9 @@ func testMapRemoveMatching(t *testing.T, builder baseMapCollIntBuilder) {
15391557
t.Errorf("RemoveMatching() did not remove correctly from values counter")
15401558
}
15411559
}
1560+
if count != tt.want5 {
1561+
t.Errorf("RemoveMatching() returned wrong count: %v, but wanted = %v", count, tt.want5)
1562+
}
15421563
})
15431564
}
15441565
}

mapcmp.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ func (c *comfyCmpMap[K, V]) RemoveMany(keys []K) {
190190
c.removeMany(keys)
191191
}
192192

193-
func (c *comfyCmpMap[K, V]) RemoveMatching(predicate Predicate[Pair[K, V]]) {
193+
func (c *comfyCmpMap[K, V]) RemoveMatching(predicate Predicate[Pair[K, V]]) (count int) {
194194
newS := []Pair[K, V](nil)
195195
newM := make(map[K]Pair[K, V])
196196
newKP := make(map[K]int)
@@ -204,13 +204,16 @@ func (c *comfyCmpMap[K, V]) RemoveMatching(predicate Predicate[Pair[K, V]]) {
204204
newKP[pair.Key()] = idx
205205
newVC.Increment(pair.Val())
206206
idx++
207+
} else {
208+
count++
207209
}
208210
}
209211

210212
c.s = newS
211213
c.m = newM
212214
c.kp = newKP
213215
c.vc = newVC
216+
return count
214217
}
215218

216219
func (c *comfyCmpMap[K, V]) RemoveValues(v V) {

mutable_cases_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,48 +111,55 @@ func getRemoveMatchingCases(builder mutableIntTestBuilder) []mutableIntTestCase
111111
args: mutableIntTestArgs{predicate: func(v int) bool { return true }},
112112
want1: []int(nil),
113113
want2: map[int]int{},
114+
want3: 0,
114115
},
115116
{
116117
name: "RemoveMatching() on one-item collection",
117118
coll: builder.One(),
118119
args: mutableIntTestArgs{predicate: func(v int) bool { return v == 111 }},
119120
want1: []int(nil),
120121
want2: map[int]int{},
122+
want3: 1,
121123
},
122124
{
123125
name: "RemoveMatching() on three-item collection",
124126
coll: builder.Three(),
125127
args: mutableIntTestArgs{predicate: func(v int) bool { return v == 222 }},
126128
want1: []int{111, 333},
127129
want2: map[int]int{111: 1, 333: 1},
130+
want3: 1,
128131
},
129132
{
130133
name: "RemoveMatching() on three-item collection, all false",
131134
coll: builder.Three(),
132135
args: mutableIntTestArgs{predicate: func(v int) bool { return false }},
133136
want1: []int{111, 222, 333},
134137
want2: map[int]int{111: 1, 222: 1, 333: 1},
138+
want3: 0,
135139
},
136140
{
137141
name: "RemoveMatching() on three-item collection, all true",
138142
coll: builder.Three(),
139143
args: mutableIntTestArgs{predicate: func(v int) bool { return true }},
140144
want1: []int(nil),
141145
want2: map[int]int{},
146+
want3: 3,
142147
},
143148
{
144149
name: "RemoveMatching() on three-item collection, some mod 2",
145150
coll: builder.Three(),
146151
args: mutableIntTestArgs{predicate: func(v int) bool { return v%2 == 0 }},
147152
want1: []int{111, 333},
148153
want2: map[int]int{111: 1, 333: 1},
154+
want3: 1,
149155
},
150156
{
151157
name: "RemoveMatching() on three-item collection, some not mod 2",
152158
coll: builder.Three(),
153159
args: mutableIntTestArgs{predicate: func(v int) bool { return v%2 != 0 }},
154160
want1: []int{222},
155161
want2: map[int]int{222: 1},
162+
want3: 2,
156163
},
157164
}
158165
}
@@ -161,7 +168,7 @@ func testRemoveMatching(t *testing.T, builder mutableIntTestBuilder) {
161168
cases := getRemoveMatchingCases(builder)
162169
for _, tt := range cases {
163170
t.Run(tt.name, func(t *testing.T) {
164-
tt.coll.RemoveMatching(tt.args.predicate)
171+
count := tt.coll.RemoveMatching(tt.args.predicate)
165172

166173
actualSlice := builder.extractUnderlyingSlice(tt.coll)
167174
actualVC := builder.extractUnderlyingValsCount(tt.coll)
@@ -172,6 +179,9 @@ func testRemoveMatching(t *testing.T, builder mutableIntTestBuilder) {
172179
if actualVC != nil && !reflect.DeepEqual(actualVC, tt.want2) {
173180
t.Errorf("RemoveMatching() did not remove correctly from values counter")
174181
}
182+
if count != tt.want3 {
183+
t.Errorf("RemoveMatching() returned wrong count: %v, but wanted = %v", count, tt.want3)
184+
}
175185
})
176186
}
177187
}

sequence.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ func (c *comfySeq[V]) RemoveAt(i int) (removed V, err error) {
9393
return removed, nil
9494
}
9595

96-
func (c *comfySeq[V]) RemoveMatching(predicate Predicate[V]) {
97-
c.s = sliceRemoveMatching(c.s, predicate)
96+
func (c *comfySeq[V]) RemoveMatching(predicate Predicate[V]) (count int) {
97+
c.s, count = sliceRemoveMatching(c.s, predicate)
98+
return count
9899
}
99100

100101
func (c *comfySeq[V]) Reverse() {

sequencecmp.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,20 @@ func (c *comfyCmpSeq[V]) RemoveAt(i int) (removed V, err error) {
140140
return removed, nil
141141
}
142142

143-
func (c *comfyCmpSeq[V]) RemoveMatching(predicate Predicate[V]) {
143+
func (c *comfyCmpSeq[V]) RemoveMatching(predicate Predicate[V]) (count int) {
144144
newS := []V(nil)
145145
newVC := newValuesCounter[V]()
146146
for _, v := range c.s {
147147
if !predicate(v) {
148148
newS = append(newS, v)
149149
newVC.Increment(v)
150+
} else {
151+
count++
150152
}
151153
}
152154
c.s = newS
153155
c.vc = newVC
156+
return count
154157
}
155158

156159
func (c *comfyCmpSeq[V]) RemoveValues(v V) {

0 commit comments

Comments
 (0)