Skip to content

Commit 28a4d94

Browse files
committed
Merge branch 'oswaldom-code-feat-adding-chunk-map'
2 parents 6b110b3 + 4a03b54 commit 28a4d94

File tree

4 files changed

+127
-0
lines changed

4 files changed

+127
-0
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,6 +1329,27 @@ mergedMaps := lo.Assign(
13291329

13301330
[[play](https://go.dev/play/p/VhwfJOyxf5o)]
13311331

1332+
### ChunkEntries
1333+
1334+
Splits a map into an array of elements in groups of a length equal to its size. If the map cannot be split evenly, the final chunk will contain the remaining elements.
1335+
1336+
```go
1337+
maps := lo.ChunkEntries(
1338+
map[string]int{
1339+
"a": 1,
1340+
"b": 2,
1341+
"c": 3,
1342+
"d": 4,
1343+
"e": 5,
1344+
},
1345+
3,
1346+
)
1347+
// []map[string]int{
1348+
// {"a": 1, "b": 2, "c": 3},
1349+
// {"d": 4, "e": 5},
1350+
// }
1351+
```
1352+
13321353
### MapKeys
13331354

13341355
Manipulates a map keys and transforms it to a map of another type.

map.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,46 @@ func Assign[K comparable, V any, Map ~map[K]V](maps ...Map) Map {
247247
return out
248248
}
249249

250+
// ChunkEntries splits a map into an array of elements in groups of a length equal to its size. If the map cannot be split evenly,
251+
// the final chunk will contain the remaining elements.
252+
func ChunkEntries[K comparable, V any](m map[K]V, size int) []map[K]V {
253+
if size <= 0 {
254+
panic("The chunk size must be greater than 0")
255+
}
256+
257+
keys := make([]K, 0, len(m))
258+
for key := range m {
259+
keys = append(keys, key)
260+
}
261+
262+
if len(keys) == 0 {
263+
return []map[K]V{}
264+
}
265+
266+
chunksNum := len(keys) / size
267+
if len(keys)%size != 0 {
268+
chunksNum += 1
269+
}
270+
271+
result := make([]map[K]V, 0, chunksNum)
272+
273+
for i := 0; i < chunksNum; i++ {
274+
start := i * size
275+
end := (i + 1) * size
276+
if end > len(keys) {
277+
end = len(keys)
278+
}
279+
280+
chunk := make(map[K]V)
281+
for _, key := range keys[start:end] {
282+
chunk[key] = m[key]
283+
}
284+
result = append(result, chunk)
285+
}
286+
287+
return result
288+
}
289+
250290
// MapKeys manipulates a map keys and transforms it to a map of another type.
251291
// Play: https://go.dev/play/p/9_4WPIqOetJ
252292
func MapKeys[K comparable, V any, R comparable](in map[K]V, iteratee func(value V, key K) R) map[R]V {

map_example_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,26 @@ func ExampleAssign() {
168168
// Output: 3 1 3 4
169169
}
170170

171+
func ExampleChunkEntries() {
172+
result := ChunkEntries(
173+
map[string]int{
174+
"a": 1,
175+
"b": 2,
176+
"c": 3,
177+
"d": 4,
178+
"e": 5,
179+
},
180+
3,
181+
)
182+
183+
for i := range result {
184+
fmt.Printf("%d\n", len(result[i]))
185+
}
186+
// Output:
187+
// 3
188+
// 2
189+
}
190+
171191
func ExampleMapKeys() {
172192
kv := map[int]int{1: 1, 2: 2, 3: 3, 4: 4}
173193

map_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,52 @@ func TestAssign(t *testing.T) {
332332
is.IsType(after, before, "type preserved")
333333
}
334334

335+
func TestChunkEntries(t *testing.T) {
336+
t.Parallel()
337+
is := assert.New(t)
338+
339+
result1 := ChunkEntries(map[string]int{"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}, 2)
340+
result2 := ChunkEntries(map[string]int{"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}, 3)
341+
result3 := ChunkEntries(map[string]int{}, 2)
342+
result4 := ChunkEntries(map[string]int{"a": 1}, 2)
343+
result5 := ChunkEntries(map[string]int{"a": 1, "b": 2}, 1)
344+
345+
expectedCount1 := 3
346+
expectedCount2 := 2
347+
expectedCount3 := 0
348+
expectedCount4 := 1
349+
expectedCount5 := 2
350+
351+
is.Len(result1, expectedCount1)
352+
is.Len(result2, expectedCount2)
353+
is.Len(result3, expectedCount3)
354+
is.Len(result4, expectedCount4)
355+
is.Len(result5, expectedCount5)
356+
357+
is.PanicsWithValue("The chunk size must be greater than 0", func() {
358+
ChunkEntries(map[string]int{"a": 1}, 0)
359+
})
360+
is.PanicsWithValue("The chunk size must be greater than 0", func() {
361+
ChunkEntries(map[string]int{"a": 1}, -1)
362+
})
363+
364+
type myStruct struct {
365+
Name string
366+
Value int
367+
}
368+
369+
allStructs := []myStruct{{"one", 1}, {"two", 2}, {"three", 3}}
370+
nonempty := ChunkEntries(map[string]myStruct{"a": allStructs[0], "b": allStructs[1], "c": allStructs[2]}, 2)
371+
is.Len(nonempty, 2)
372+
373+
originalMap := map[string]int{"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}
374+
result6 := ChunkEntries(originalMap, 2)
375+
for k := range result6[0] {
376+
result6[0][k] = 10
377+
}
378+
is.Equal(originalMap, map[string]int{"a": 1, "b": 2, "c": 3, "d": 4, "e": 5})
379+
}
380+
335381
func TestMapKeys(t *testing.T) {
336382
t.Parallel()
337383
is := assert.New(t)

0 commit comments

Comments
 (0)