authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-01-29 15:49:47+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-01-29 15:49:47+02:00
log88edde4edc2d744a2f92b3f2b9417f1ec9e9af81
treee27006a51ad39a2e7e8ab1a66b7b9cb0cb6d2439
parent8ca9452a82bbb8936fc983ac0ef699e2576f952c
parent100b8a244cdbcd16669e6b81ab82d6a628559e22
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #9915 from zzyxyzz/indexOfMinMax

std.mem: add indexOfMin and indexOfMax

1 files changed, 98 insertions(+), 2 deletions(-)

lib/std/mem.zig+98-2
...@@ -2146,6 +2146,7 @@ fn testWriteIntImpl() !void {...@@ -2146,6 +2146,7 @@ fn testWriteIntImpl() !void {
2146/// Returns the smallest number in a slice. O(n).2146/// Returns the smallest number in a slice. O(n).
2147/// `slice` must not be empty.2147/// `slice` must not be empty.
2148pub fn min(comptime T: type, slice: []const T) T {2148pub fn min(comptime T: type, slice: []const T) T {
2149 assert(slice.len > 0);
2149 var best = slice[0];2150 var best = slice[0];
2150 for (slice[1..]) |item| {2151 for (slice[1..]) |item| {
2151 best = math.min(best, item);2152 best = math.min(best, item);
...@@ -2154,12 +2155,15 @@ pub fn min(comptime T: type, slice: []const T) T {...@@ -2154,12 +2155,15 @@ pub fn min(comptime T: type, slice: []const T) T {
2154}2155}
21552156
2156test "mem.min" {2157test "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');
2158}2161}
21592162
2160/// Returns the largest number in a slice. O(n).2163/// Returns the largest number in a slice. O(n).
2161/// `slice` must not be empty.2164/// `slice` must not be empty.
2162pub fn max(comptime T: type, slice: []const T) T {2165pub fn max(comptime T: type, slice: []const T) T {
2166 assert(slice.len > 0);
2163 var best = slice[0];2167 var best = slice[0];
2164 for (slice[1..]) |item| {2168 for (slice[1..]) |item| {
2165 best = math.max(best, item);2169 best = math.max(best, item);
...@@ -2168,7 +2172,99 @@ pub fn max(comptime T: type, slice: []const T) T {...@@ -2168,7 +2172,99 @@ pub fn max(comptime T: type, slice: []const T) T {
2168}2172}
21692173
2170test "mem.max" {2174test "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.
2183pub 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
2194test "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.
2202pub 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
2215test "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.
2223pub 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
2236test "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.
2245pub 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
2264test "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 });
2172}2268}
21732269
2174pub fn swap(comptime T: type, a: *T, b: *T) void {2270pub fn swap(comptime T: type, a: *T, b: *T) void {