Skip to content

Commit 2b89f4d

Browse files
committed
Add IndexOfMax functions for finding index of maximum element
Implements argMax functionality requested in GitHub issue #139. Features: - IndexOfMaxInt, IndexOfMaxInt8, IndexOfMaxInt16, IndexOfMaxInt32, IndexOfMaxInt64 - IndexOfMaxFloat32, IndexOfMaxFloat64 - IndexOfMaxString - Returns index of maximum element in slice/array - Returns first occurrence index if there are duplicates - Panics on empty input as requested in issue - Follows go-funk naming conventions (IndexOfMax vs ArgMax) - Comprehensive test coverage including edge cases Fixes #139
1 parent 045ef11 commit 2b89f4d

2 files changed

Lines changed: 277 additions & 0 deletions

File tree

indexofmax.go

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
package funk
2+
3+
import "strings"
4+
5+
// IndexOfMaxInt validates the input, compares the elements and returns the index of the maximum element in an array/slice.
6+
// If there are duplicate occurrences of max element, only return the first one.
7+
// This function implements the argMax functionality requested in GitHub issue #139.
8+
// It accepts []int
9+
// It returns int
10+
func IndexOfMaxInt(i []int) int {
11+
if len(i) == 0 {
12+
panic("arg is an empty array/slice")
13+
}
14+
var max int
15+
var maxIndex int
16+
for idx := 0; idx < len(i); idx++ {
17+
item := i[idx]
18+
if idx == 0 {
19+
max = item
20+
maxIndex = 0
21+
continue
22+
}
23+
if item > max {
24+
max = item
25+
maxIndex = idx
26+
}
27+
}
28+
return maxIndex
29+
}
30+
31+
// IndexOfMaxInt8 validates the input, compares the elements and returns the index of the maximum element in an array/slice.
32+
// If there are duplicate occurrences of max element, only return the first one.
33+
// It accepts []int8
34+
// It returns int
35+
func IndexOfMaxInt8(i []int8) int {
36+
if len(i) == 0 {
37+
panic("arg is an empty array/slice")
38+
}
39+
var max int8
40+
var maxIndex int
41+
for idx := 0; idx < len(i); idx++ {
42+
item := i[idx]
43+
if idx == 0 {
44+
max = item
45+
maxIndex = 0
46+
continue
47+
}
48+
if item > max {
49+
max = item
50+
maxIndex = idx
51+
}
52+
}
53+
return maxIndex
54+
}
55+
56+
// IndexOfMaxInt16 validates the input, compares the elements and returns the index of the maximum element in an array/slice.
57+
// If there are duplicate occurrences of max element, only return the first one.
58+
// It accepts []int16
59+
// It returns int
60+
func IndexOfMaxInt16(i []int16) int {
61+
if len(i) == 0 {
62+
panic("arg is an empty array/slice")
63+
}
64+
var max int16
65+
var maxIndex int
66+
for idx := 0; idx < len(i); idx++ {
67+
item := i[idx]
68+
if idx == 0 {
69+
max = item
70+
maxIndex = 0
71+
continue
72+
}
73+
if item > max {
74+
max = item
75+
maxIndex = idx
76+
}
77+
}
78+
return maxIndex
79+
}
80+
81+
// IndexOfMaxInt32 validates the input, compares the elements and returns the index of the maximum element in an array/slice.
82+
// If there are duplicate occurrences of max element, only return the first one.
83+
// It accepts []int32
84+
// It returns int
85+
func IndexOfMaxInt32(i []int32) int {
86+
if len(i) == 0 {
87+
panic("arg is an empty array/slice")
88+
}
89+
var max int32
90+
var maxIndex int
91+
for idx := 0; idx < len(i); idx++ {
92+
item := i[idx]
93+
if idx == 0 {
94+
max = item
95+
maxIndex = 0
96+
continue
97+
}
98+
if item > max {
99+
max = item
100+
maxIndex = idx
101+
}
102+
}
103+
return maxIndex
104+
}
105+
106+
// IndexOfMaxInt64 validates the input, compares the elements and returns the index of the maximum element in an array/slice.
107+
// If there are duplicate occurrences of max element, only return the first one.
108+
// It accepts []int64
109+
// It returns int
110+
func IndexOfMaxInt64(i []int64) int {
111+
if len(i) == 0 {
112+
panic("arg is an empty array/slice")
113+
}
114+
var max int64
115+
var maxIndex int
116+
for idx := 0; idx < len(i); idx++ {
117+
item := i[idx]
118+
if idx == 0 {
119+
max = item
120+
maxIndex = 0
121+
continue
122+
}
123+
if item > max {
124+
max = item
125+
maxIndex = idx
126+
}
127+
}
128+
return maxIndex
129+
}
130+
131+
// IndexOfMaxFloat32 validates the input, compares the elements and returns the index of the maximum element in an array/slice.
132+
// If there are duplicate occurrences of max element, only return the first one.
133+
// It accepts []float32
134+
// It returns int
135+
func IndexOfMaxFloat32(i []float32) int {
136+
if len(i) == 0 {
137+
panic("arg is an empty array/slice")
138+
}
139+
var max float32
140+
var maxIndex int
141+
for idx := 0; idx < len(i); idx++ {
142+
item := i[idx]
143+
if idx == 0 {
144+
max = item
145+
maxIndex = 0
146+
continue
147+
}
148+
if item > max {
149+
max = item
150+
maxIndex = idx
151+
}
152+
}
153+
return maxIndex
154+
}
155+
156+
// IndexOfMaxFloat64 validates the input, compares the elements and returns the index of the maximum element in an array/slice.
157+
// If there are duplicate occurrences of max element, only return the first one.
158+
// It accepts []float64
159+
// It returns int
160+
func IndexOfMaxFloat64(i []float64) int {
161+
if len(i) == 0 {
162+
panic("arg is an empty array/slice")
163+
}
164+
var max float64
165+
var maxIndex int
166+
for idx := 0; idx < len(i); idx++ {
167+
item := i[idx]
168+
if idx == 0 {
169+
max = item
170+
maxIndex = 0
171+
continue
172+
}
173+
if item > max {
174+
max = item
175+
maxIndex = idx
176+
}
177+
}
178+
return maxIndex
179+
}
180+
181+
// IndexOfMaxString validates the input, compares the elements and returns the index of the maximum element in an array/slice.
182+
// If there are duplicate occurrences of max element, only return the first one.
183+
// It accepts []string
184+
// It returns int
185+
func IndexOfMaxString(i []string) int {
186+
if len(i) == 0 {
187+
panic("arg is an empty array/slice")
188+
}
189+
var max string
190+
var maxIndex int
191+
for idx := 0; idx < len(i); idx++ {
192+
item := i[idx]
193+
if idx == 0 {
194+
max = item
195+
maxIndex = 0
196+
continue
197+
}
198+
if compareStringsIndexOfMax(max, item) == item {
199+
max = item
200+
maxIndex = idx
201+
}
202+
}
203+
return maxIndex
204+
}
205+
206+
// compareStringsIndexOfMax uses the strings.Compare method to compare two strings, and returns the greater one.
207+
func compareStringsIndexOfMax(max, current string) string {
208+
r := strings.Compare(strings.ToLower(max), strings.ToLower(current))
209+
if r > 0 {
210+
return max
211+
}
212+
return current
213+
}

indexofmax_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package funk
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
// TestIndexOfMaxIssue139Example tests the exact example provided in GitHub issue #139
10+
func TestIndexOfMaxIssue139Example(t *testing.T) {
11+
nums := []int64{8, 3, 4, 44, 0}
12+
result := IndexOfMaxInt64(nums)
13+
assert.Equal(t, 3, result, "Should return index 3 for the example in issue #139")
14+
assert.Equal(t, int64(44), nums[result], "The element at returned index should be 44")
15+
}
16+
17+
func TestIndexOfMaxWithArrayNumericInput(t *testing.T) {
18+
// Test Data
19+
d1 := []int{8, 3, 4, 44, 0}
20+
d1dup := []int{44, 3, 4, 44, 0} // duplicate max at beginning
21+
n1 := []int{}
22+
23+
// Calls
24+
r1 := IndexOfMaxInt(d1)
25+
r1dup := IndexOfMaxInt(d1dup)
26+
27+
// Assertions
28+
assert.Equal(t, 3, r1, "It should return the index of max value in array")
29+
assert.Equal(t, 0, r1dup, "It should return the first index of duplicate max value")
30+
assert.Panics(t, func() { IndexOfMaxInt(n1) }, "It should panic")
31+
}
32+
33+
func TestIndexOfMaxWithArrayFloatInput(t *testing.T) {
34+
// Test Data
35+
d1 := []float64{2, 38.3, 4, 4.4, 4}
36+
d1dup := []float64{38.3, 2, 4, 38.3, 4} // duplicate max at beginning
37+
n1 := []float64{}
38+
39+
// Calls
40+
r1 := IndexOfMaxFloat64(d1)
41+
r1dup := IndexOfMaxFloat64(d1dup)
42+
43+
// Assertions
44+
assert.Equal(t, 1, r1, "It should return the index of max value in array")
45+
assert.Equal(t, 0, r1dup, "It should return the first index of duplicate max value")
46+
assert.Panics(t, func() { IndexOfMaxFloat64(n1) }, "It should panic")
47+
}
48+
49+
func TestIndexOfMaxSingleElement(t *testing.T) {
50+
// Test Data with single elements
51+
d1 := []int{42}
52+
d2 := []float64{3.14}
53+
d3 := []string{"hello"}
54+
55+
// Calls
56+
r1 := IndexOfMaxInt(d1)
57+
r2 := IndexOfMaxFloat64(d2)
58+
r3 := IndexOfMaxString(d3)
59+
60+
// Assertions
61+
assert.Equal(t, 0, r1, "Single element should return index 0")
62+
assert.Equal(t, 0, r2, "Single element should return index 0")
63+
assert.Equal(t, 0, r3, "Single element should return index 0")
64+
}

0 commit comments

Comments
 (0)