Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions lib/std/mem.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4103,7 +4103,9 @@ pub fn replaceScalar(comptime T: type, slice: []T, match: T, replacement: T) voi
}
}

/// Collapse consecutive duplicate elements into one entry.
/// Collapse all consecutive occurrences of `elem` into one entry.
///
/// See also `collapseRepeatsAll`
pub fn collapseRepeatsLen(comptime T: type, slice: []T, elem: T) usize {
if (slice.len == 0) return 0;
var write_idx: usize = 1;
Expand All @@ -4117,7 +4119,9 @@ pub fn collapseRepeatsLen(comptime T: type, slice: []T, elem: T) usize {
return write_idx;
}

/// Collapse consecutive duplicate elements into one entry.
/// Collapse all consecutive occurrences of `elem` into one entry.
///
/// See also `collapseRepeatsAll`
pub fn collapseRepeats(comptime T: type, slice: []T, elem: T) []T {
return slice[0..collapseRepeatsLen(T, slice, elem)];
}
Expand All @@ -4141,6 +4145,42 @@ test collapseRepeats {
try testCollapseRepeats("//a///a////", '/', "/a/a/");
}

/// Collapse consecutive duplicates into one entry.
///
/// See also `collapseRepeats`
pub fn collapseRepeatsAll(comptime T: type, slice: []T) []T {
if (slice.len == 0) return slice;

var write_index: usize = 1;
for (slice[0 .. slice.len - 1], slice[1..]) |elem, next| {
if (elem != next) {
slice[write_index] = next;
write_index += 1;
}
}
return slice[0..write_index];
}

test collapseRepeatsAll {
try std.testing.expectEqualSlices(u8, &.{}, collapseRepeatsAll(u8, &.{}));
{
var array: [1]u8 = .{0};
try std.testing.expectEqualSlices(u8, &.{0}, collapseRepeatsAll(u8, &array));
}
{
var array: [2]u8 = .{ 0, 0 };
try std.testing.expectEqualSlices(u8, &.{0}, collapseRepeatsAll(u8, &array));
}
{
var array: [2]u8 = .{ 0, 1 };
try std.testing.expectEqualSlices(u8, &.{ 0, 1 }, collapseRepeatsAll(u8, &array));
}
{
var array: [10]u8 = .{ 1, 0, 1, 1, 10, 10, 10, 0, 0, 0 };
try std.testing.expectEqualSlices(u8, &.{ 1, 0, 1, 10, 0 }, collapseRepeatsAll(u8, &array));
}
}

/// Calculate the size needed in an output buffer to perform a replacement.
/// The needle must not be empty.
pub fn replacementSize(comptime T: type, input: []const T, needle: []const T, replacement: []const T) usize {
Expand Down