Skip to content

Commit 47d72d9

Browse files
authored
Fix Enum.slice/2 for ranges with step > 1 sliced by step > 1 (#15144)
When slicing a Range with step > 1 using a slice range that also has step > 1, the formula for calculating the step in the slicer function was incorrect.
1 parent 9a663cf commit 47d72d9

2 files changed

Lines changed: 11 additions & 1 deletion

File tree

lib/elixir/lib/enum.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5224,7 +5224,7 @@ defimpl Enumerable, for: Range do
52245224
end
52255225

52265226
def slice(first.._//step = range) do
5227-
{:ok, Range.size(range), &slice(first + &1 * step, step + &3 - 1, &2)}
5227+
{:ok, Range.size(range), &slice(first + &1 * step, step * &3, &2)}
52285228
end
52295229

52305230
# TODO: Remove me on v2.0

lib/elixir/test/elixir/enum_test.exs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2341,6 +2341,16 @@ defmodule EnumTest.Range do
23412341
assert Enum.slice(1..10//2, -5..-1) == [1, 3, 5, 7, 9]
23422342
assert Enum.slice(1..10//2, -5..-3) == [1, 3, 5]
23432343

2344+
# Range with step > 1 sliced by a range with step > 1
2345+
assert Enum.slice(1..10//2, 0..4//2) == [1, 5, 9]
2346+
assert Enum.slice(1..10//2, 0..4//3) == [1, 7]
2347+
assert Enum.slice(1..10//2, 1..4//2) == [3, 7]
2348+
assert Enum.slice(0..20//3, 0..6//2) == [0, 6, 12, 18]
2349+
2350+
# Range with negative step sliced by a range with step > 1
2351+
assert Enum.slice(10..1//-2, 0..4//2) == [10, 6, 2]
2352+
assert Enum.slice(20..0//-3, 0..6//2) == [20, 14, 8, 2]
2353+
23442354
assert_raise ArgumentError,
23452355
"Enum.slice/2 does not accept ranges with negative steps, got: 1..3//-2",
23462356
fn -> Enum.slice(1..5, 1..3//-2) end

0 commit comments

Comments
 (0)