Skip to content

Commit

Permalink
Add Indexable#index! overloads with offset parameter (#12089)
Browse files Browse the repository at this point in the history
  • Loading branch information
HertzDevil authored Sep 5, 2022
1 parent d642d4f commit a9ce021
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
22 changes: 22 additions & 0 deletions spec/std/indexable_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,28 @@ describe Indexable do
end
end

describe "#index!" do
it "offset type" do
indexable = SafeIndexable.new(3)
indexable.index!(1, 0_i64).should eq 1
indexable.index!(1, 0_i64).should be_a(Int64)
end

it "raises if no element is found" do
indexable = SafeIndexable.new(3)
expect_raises(Enumerable::NotFoundError) { indexable.index!(0, -100) }
expect_raises(Enumerable::NotFoundError) { indexable.index!(0, -4) }
expect_raises(Enumerable::NotFoundError) { indexable.index!(0, 1) }
expect_raises(Enumerable::NotFoundError) { indexable.index!(0, 3) }
expect_raises(Enumerable::NotFoundError) { indexable.index!(0, 100) }

expect_raises(Enumerable::NotFoundError) { indexable.index!(-4) { true } }
expect_raises(Enumerable::NotFoundError) { indexable.index!(3) { true } }
expect_raises(Enumerable::NotFoundError) { indexable.index!(2) { false } }
expect_raises(Enumerable::NotFoundError) { indexable.index!(-3) { false } }
end
end

describe "#rindex" do
it "does rindex with big negative offset" do
indexable = SafeIndexable.new(3)
Expand Down
26 changes: 24 additions & 2 deletions src/indexable.cr
Original file line number Diff line number Diff line change
Expand Up @@ -742,8 +742,8 @@ module Indexable(T)
hasher
end

# Returns the index of the first appearance of *value* in `self`
# starting from the given *offset*, or `nil` if the value is not in `self`.
# Returns the index of the first appearance of *object* in `self`
# starting from the given *offset*, or `nil` if *object* is not in `self`.
#
# ```
# [1, 2, 3, 1, 2, 3].index(2, offset: 2) # => 4
Expand Down Expand Up @@ -771,6 +771,28 @@ module Indexable(T)
nil
end

# Returns the index of the first appearance of *obj* in `self`
# starting from the given *offset*. Raises `Enumerable::NotFoundError` if
# *obj* is not in `self`.
#
# ```
# [1, 2, 3, 1, 2, 3].index!(2, offset: 2) # => 4
# ```
def index!(obj, offset : Int = 0)
index(obj, offset) || raise Enumerable::NotFoundError.new
end

# Returns the index of the first object in `self` for which the block
# is truthy, starting from the given *offset*. Raises
# `Enumerable::NotFoundError` if no match is found.
#
# ```
# [1, 2, 3, 1, 2, 3].index!(offset: 2) { |x| x < 2 } # => 3
# ```
def index!(offset : Int = 0, & : T ->)
index(offset) { |e| yield e } || raise Enumerable::NotFoundError.new
end

# Returns the last element of `self` if it's not empty, or raises `IndexError`.
#
# ```
Expand Down

0 comments on commit a9ce021

Please sign in to comment.