Skip to content
Open
Show file tree
Hide file tree
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
50 changes: 50 additions & 0 deletions builtin/arrayview.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,56 @@ pub fn[T : Eq] ArrayView::ends_with(
}
}

///|
/// Returns a sub-view with `prefix` removed from the start, or `None` if the
/// view does not start with `prefix`. The returned view shares the original
/// backing array — no allocation.
///
/// Example:
///
/// ```mbt check
/// test {
/// let v = [1, 2, 3, 4, 5][:]
/// inspect(v.strip_prefix([1, 2][:]), content="Some([3, 4, 5])")
/// inspect(v.strip_prefix([2, 3][:]), content="None")
/// }
/// ```
pub fn[T : Eq] ArrayView::strip_prefix(
self : ArrayView[T],
prefix : ArrayView[T],
) -> ArrayView[T]? {
if self.starts_with(prefix) {
Some(self[prefix.length():])
} else {
None
}
}

///|
/// Returns a sub-view with `suffix` removed from the end, or `None` if the
/// view does not end with `suffix`. The returned view shares the original
/// backing array — no allocation.
///
/// Example:
///
/// ```mbt check
/// test {
/// let v = [1, 2, 3, 4, 5][:]
/// inspect(v.strip_suffix([4, 5][:]), content="Some([1, 2, 3])")
/// inspect(v.strip_suffix([3, 4][:]), content="None")
/// }
/// ```
pub fn[T : Eq] ArrayView::strip_suffix(
self : ArrayView[T],
suffix : ArrayView[T],
) -> ArrayView[T]? {
if self.ends_with(suffix) {
Some(self[:self.length() - suffix.length()])
} else {
None
}
}

///|
/// Performs a binary search on a sorted array view.
///
Expand Down
71 changes: 71 additions & 0 deletions builtin/arrayview_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -807,3 +807,74 @@ test "ArrayView::filter_map does not mutate source" {
let _ = v.filter_map(x => Some(x + 100))
inspect(arr, content="[1, 2, 3, 4]")
}

///|
test "ArrayView::strip_prefix basic" {
let v = [1, 2, 3, 4, 5][:]
inspect(v.strip_prefix([1, 2][:]), content="Some([3, 4, 5])")
inspect(v.strip_prefix([2, 3][:]), content="None")
}

///|
test "ArrayView::strip_prefix empty prefix" {
let v = [1, 2, 3][:]
inspect(v.strip_prefix([][:]), content="Some([1, 2, 3])")
}

///|
test "ArrayView::strip_prefix full match" {
let v = [1, 2, 3][:]
inspect(v.strip_prefix([1, 2, 3][:]), content="Some([])")
}

///|
test "ArrayView::strip_prefix too long" {
let v = [1, 2][:]
inspect(v.strip_prefix([1, 2, 3][:]), content="None")
}

///|
test "ArrayView::strip_prefix on sliced view" {
let v = [0, 1, 2, 3, 4][1:]
inspect(v.strip_prefix([1, 2][:]), content="Some([3, 4])")
}

///|
test "ArrayView::strip_prefix shares backing" {
let arr = [1, 2, 3, 4, 5]
guard arr[:].strip_prefix([1, 2][:]) is Some(rest)
// Mutating the source propagates to the stripped view.
arr[2] = 99
inspect(rest, content="[99, 4, 5]")
}

///|
test "ArrayView::strip_suffix basic" {
let v = [1, 2, 3, 4, 5][:]
inspect(v.strip_suffix([4, 5][:]), content="Some([1, 2, 3])")
inspect(v.strip_suffix([3, 4][:]), content="None")
}

///|
test "ArrayView::strip_suffix empty suffix" {
let v = [1, 2, 3][:]
inspect(v.strip_suffix([][:]), content="Some([1, 2, 3])")
}

///|
test "ArrayView::strip_suffix full match" {
let v = [1, 2, 3][:]
inspect(v.strip_suffix([1, 2, 3][:]), content="Some([])")
}

///|
test "ArrayView::strip_suffix too long" {
let v = [1, 2][:]
inspect(v.strip_suffix([0, 1, 2][:]), content="None")
}

///|
test "ArrayView::strip_suffix on sliced view" {
let v = [0, 1, 2, 3, 4][:4]
inspect(v.strip_suffix([2, 3][:]), content="Some([0, 1])")
}
2 changes: 2 additions & 0 deletions builtin/pkg.generated.mbti
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ pub fn[T : Eq] ArrayView::search(Self[T], T) -> Int?
pub fn[T] ArrayView::search_by(Self[T], (T) -> Bool raise?) -> Int? raise?
pub fn[T] ArrayView::start_offset(Self[T]) -> Int
pub fn[T : Eq] ArrayView::starts_with(Self[T], Self[T]) -> Bool
pub fn[T : Eq] ArrayView::strip_prefix(Self[T], Self[T]) -> Self[T]?
pub fn[T : Eq] ArrayView::strip_suffix(Self[T], Self[T]) -> Self[T]?
pub fn[T] ArrayView::suffixes(Self[T], include_empty? : Bool) -> Iter[Self[T]]
pub fn[T] ArrayView::to_array(Self[T]) -> Array[T]
#alias("_[_:_]")
Expand Down
Loading