Type Function equalRange [src]

Returns a tuple of the lower and upper indices in items between which all elements return .eq when given to compareFn. If no element in items returns .eq, both indices are the index of the first element in items returning .gt. If no element in items returns .gt, both indices equal items.len. items must be sorted in ascending order with respect to compareFn: [0] [len] ┌───┬───┬─/ /─┬───┬───┬───┬─/ /─┬───┬───┬───┬─/ /─┬───┐ │.lt│.lt│ \ \ │.lt│.eq│.eq│ \ \ │.eq│.gt│.gt│ \ \ │.gt│ └───┴───┴─/ /─┴───┴───┴───┴─/ /─┴───┴───┴───┴─/ /─┴───┘ ├─────────────────┼─────────────────┼─────────────────┤ ↳ zero or more ↳ zero or more ↳ zero or more ├─────────────────┤ ↳ returned range O(log n) time complexity. See also: binarySearch, lowerBound, upperBound, partitionPoint.

Prototype

pub fn equalRange( comptime T: type, items: []const T, context: anytype, comptime compareFn: fn (@TypeOf(context), T) std.math.Order, ) struct { usize, usize }

Parameters

T: typeitems: []const TcompareFn: fn (@TypeOf(context), T) std.math.Order

Example

test equalRange { const S = struct { fn orderU32(context: u32, item: u32) std.math.Order { return std.math.order(context, item); } fn orderI32(context: i32, item: i32) std.math.Order { return std.math.order(context, item); } fn orderF32(context: f32, item: f32) std.math.Order { return std.math.order(context, item); } fn orderLength(context: usize, item: []const u8) std.math.Order { return std.math.order(context, item.len); } }; try std.testing.expectEqual(.{ 0, 0 }, equalRange(i32, &[_]i32{}, @as(i32, 0), S.orderI32)); try std.testing.expectEqual(.{ 0, 0 }, equalRange(i32, &[_]i32{ 2, 4, 8, 16, 32, 64 }, @as(i32, 0), S.orderI32)); try std.testing.expectEqual(.{ 0, 1 }, equalRange(i32, &[_]i32{ 2, 4, 8, 16, 32, 64 }, @as(i32, 2), S.orderI32)); try std.testing.expectEqual(.{ 2, 2 }, equalRange(i32, &[_]i32{ 2, 4, 8, 16, 32, 64 }, @as(i32, 5), S.orderI32)); try std.testing.expectEqual(.{ 2, 3 }, equalRange(i32, &[_]i32{ 2, 4, 8, 16, 32, 64 }, @as(i32, 8), S.orderI32)); try std.testing.expectEqual(.{ 5, 6 }, equalRange(i32, &[_]i32{ 2, 4, 8, 16, 32, 64 }, @as(i32, 64), S.orderI32)); try std.testing.expectEqual(.{ 6, 6 }, equalRange(i32, &[_]i32{ 2, 4, 8, 16, 32, 64 }, @as(i32, 100), S.orderI32)); try std.testing.expectEqual(.{ 2, 6 }, equalRange(i32, &[_]i32{ 2, 4, 8, 8, 8, 8, 15, 22 }, @as(i32, 8), S.orderI32)); try std.testing.expectEqual(.{ 2, 2 }, equalRange(u32, &[_]u32{ 2, 4, 8, 16, 32, 64 }, @as(u32, 5), S.orderU32)); try std.testing.expectEqual(.{ 3, 5 }, equalRange(u32, &[_]u32{ 2, 3, 4, 5, 5 }, @as(u32, 5), S.orderU32)); try std.testing.expectEqual(.{ 1, 1 }, equalRange(f32, &[_]f32{ -54.2, -26.7, 0.0, 56.55, 100.1, 322.0 }, @as(f32, -33.4), S.orderF32)); try std.testing.expectEqual(.{ 3, 5 }, equalRange( []const u8, &[_][]const u8{ "Mars", "Venus", "Earth", "Saturn", "Uranus", "Mercury", "Jupiter", "Neptune" }, @as(usize, 6), S.orderLength, )); }

Source

pub fn equalRange( comptime T: type, items: []const T, context: anytype, comptime compareFn: fn (@TypeOf(context), T) std.math.Order, ) struct { usize, usize } { var low: usize = 0; var high: usize = items.len; while (low < high) { const mid = low + (high - low) / 2; switch (compareFn(context, items[mid])) { .gt => { low = mid + 1; }, .lt => { high = mid; }, .eq => { return .{ low + std.sort.lowerBound( T, items[low..mid], context, compareFn, ), mid + std.sort.upperBound( T, items[mid..high], context, compareFn, ), }; }, } } return .{ low, low }; }