Skip to content

Commit 88edde4

Browse files
authored
Merge pull request #9915 from zzyxyzz/indexOfMinMax
std.mem: add indexOfMin and indexOfMax
2 parents 8ca9452 + 100b8a2 commit 88edde4

File tree

1 file changed

+98
-2
lines changed

1 file changed

+98
-2
lines changed

lib/std/mem.zig

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,6 +2146,7 @@ fn testWriteIntImpl() !void {
21462146
/// Returns the smallest number in a slice. O(n).
21472147
/// `slice` must not be empty.
21482148
pub fn min(comptime T: type, slice: []const T) T {
2149+
assert(slice.len > 0);
21492150
var best = slice[0];
21502151
for (slice[1..]) |item| {
21512152
best = math.min(best, item);
@@ -2154,12 +2155,15 @@ pub fn min(comptime T: type, slice: []const T) T {
21542155
}
21552156

21562157
test "mem.min" {
2157-
try testing.expect(min(u8, "abcdefg") == 'a');
2158+
try testing.expectEqual(min(u8, "abcdefg"), 'a');
2159+
try testing.expectEqual(min(u8, "bcdefga"), 'a');
2160+
try testing.expectEqual(min(u8, "a"), 'a');
21582161
}
21592162

21602163
/// Returns the largest number in a slice. O(n).
21612164
/// `slice` must not be empty.
21622165
pub fn max(comptime T: type, slice: []const T) T {
2166+
assert(slice.len > 0);
21632167
var best = slice[0];
21642168
for (slice[1..]) |item| {
21652169
best = math.max(best, item);
@@ -2168,7 +2172,99 @@ pub fn max(comptime T: type, slice: []const T) T {
21682172
}
21692173

21702174
test "mem.max" {
2171-
try testing.expect(max(u8, "abcdefg") == 'g');
2175+
try testing.expectEqual(max(u8, "abcdefg"), 'g');
2176+
try testing.expectEqual(max(u8, "gabcdef"), 'g');
2177+
try testing.expectEqual(max(u8, "g"), 'g');
2178+
}
2179+
2180+
/// Finds the smallest and largest number in a slice. O(n).
2181+
/// Returns an anonymous struct with the fields `min` and `max`.
2182+
/// `slice` must not be empty.
2183+
pub fn minMax(comptime T: type, slice: []const T) struct { min: T, max: T } {
2184+
assert(slice.len > 0);
2185+
var minVal = slice[0];
2186+
var maxVal = slice[0];
2187+
for (slice[1..]) |item| {
2188+
minVal = math.min(minVal, item);
2189+
maxVal = math.max(maxVal, item);
2190+
}
2191+
return .{ .min = minVal, .max = maxVal };
2192+
}
2193+
2194+
test "mem.minMax" {
2195+
try testing.expectEqual(minMax(u8, "abcdefg"), .{ .min = 'a', .max = 'g' });
2196+
try testing.expectEqual(minMax(u8, "bcdefga"), .{ .min = 'a', .max = 'g' });
2197+
try testing.expectEqual(minMax(u8, "a"), .{ .min = 'a', .max = 'a' });
2198+
}
2199+
2200+
/// Returns the index of the smallest number in a slice. O(n).
2201+
/// `slice` must not be empty.
2202+
pub fn indexOfMin(comptime T: type, slice: []const T) usize {
2203+
assert(slice.len > 0);
2204+
var best = slice[0];
2205+
var index: usize = 0;
2206+
for (slice[1..]) |item, i| {
2207+
if (item < best) {
2208+
best = item;
2209+
index = i + 1;
2210+
}
2211+
}
2212+
return index;
2213+
}
2214+
2215+
test "mem.indexOfMin" {
2216+
try testing.expectEqual(indexOfMin(u8, "abcdefg"), 0);
2217+
try testing.expectEqual(indexOfMin(u8, "bcdefga"), 6);
2218+
try testing.expectEqual(indexOfMin(u8, "a"), 0);
2219+
}
2220+
2221+
/// Returns the index of the largest number in a slice. O(n).
2222+
/// `slice` must not be empty.
2223+
pub fn indexOfMax(comptime T: type, slice: []const T) usize {
2224+
assert(slice.len > 0);
2225+
var best = slice[0];
2226+
var index: usize = 0;
2227+
for (slice[1..]) |item, i| {
2228+
if (item > best) {
2229+
best = item;
2230+
index = i + 1;
2231+
}
2232+
}
2233+
return index;
2234+
}
2235+
2236+
test "mem.indexOfMax" {
2237+
try testing.expectEqual(indexOfMax(u8, "abcdefg"), 6);
2238+
try testing.expectEqual(indexOfMax(u8, "gabcdef"), 0);
2239+
try testing.expectEqual(indexOfMax(u8, "a"), 0);
2240+
}
2241+
2242+
/// Finds the indices of the smallest and largest number in a slice. O(n).
2243+
/// Returns an anonymous struct with the fields `index_min` and `index_max`.
2244+
/// `slice` must not be empty.
2245+
pub fn indexOfMinMax(comptime T: type, slice: []const T) struct { index_min: usize, index_max: usize } {
2246+
assert(slice.len > 0);
2247+
var minVal = slice[0];
2248+
var maxVal = slice[0];
2249+
var minIdx: usize = 0;
2250+
var maxIdx: usize = 0;
2251+
for (slice[1..]) |item, i| {
2252+
if (item < minVal) {
2253+
minVal = item;
2254+
minIdx = i + 1;
2255+
}
2256+
if (item > maxVal) {
2257+
maxVal = item;
2258+
maxIdx = i + 1;
2259+
}
2260+
}
2261+
return .{ .index_min = minIdx, .index_max = maxIdx };
2262+
}
2263+
2264+
test "mem.indexOfMinMax" {
2265+
try testing.expectEqual(indexOfMinMax(u8, "abcdefg"), .{ .index_min = 0, .index_max = 6 });
2266+
try testing.expectEqual(indexOfMinMax(u8, "gabcdef"), .{ .index_min = 1, .index_max = 0 });
2267+
try testing.expectEqual(indexOfMinMax(u8, "a"), .{ .index_min = 0, .index_max = 0 });
21722268
}
21732269

21742270
pub fn swap(comptime T: type, a: *T, b: *T) void {

0 commit comments

Comments
 (0)