Skip to content

Commit 7d737bc

Browse files
sabiwarajosevalim
authored andcommitted
Fix slicing MapSet with stepped range (#12667)
1 parent 3eb0742 commit 7d737bc

File tree

2 files changed

+18
-6
lines changed

2 files changed

+18
-6
lines changed

lib/elixir/lib/enum.ex

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3009,13 +3009,16 @@ defmodule Enum do
30093009

30103010
if first < count and amount > 0 do
30113011
amount = Kernel.min(amount, count - first)
3012-
amount = if step == 1, do: amount, else: div(amount - 1, step) + 1
3012+
amount = amount_with_step(amount, step)
30133013
fun.(first, amount, step)
30143014
else
30153015
[]
30163016
end
30173017
end
30183018

3019+
defp amount_with_step(amount, 1), do: amount
3020+
defp amount_with_step(amount, step), do: div(amount - 1, step) + 1
3021+
30193022
@doc """
30203023
Returns a subset list of the given `enumerable`, from `start_index` (zero-based)
30213024
with `amount` number of elements if available.
@@ -4440,15 +4443,15 @@ defmodule Enum do
44404443

44414444
if start >= 0 do
44424445
amount = Kernel.min(amount, count - start)
4443-
amount = if step == 1, do: amount, else: div(amount - 1, step) + 1
4446+
amount = amount_with_step(amount, step)
44444447
fun.(start, amount, step)
44454448
else
44464449
[]
44474450
end
44484451
end
44494452

44504453
defp slice_forward(list, start, amount, step) when is_list(list) do
4451-
amount = if step == 1, do: amount, else: div(amount - 1, step) + 1
4454+
amount = amount_with_step(amount, step)
44524455
slice_list(list, start, amount, step)
44534456
end
44544457

@@ -4458,7 +4461,7 @@ defmodule Enum do
44584461
[]
44594462

44604463
{:ok, count, fun} when is_function(fun, 1) ->
4461-
amount = Kernel.min(amount, count - start)
4464+
amount = Kernel.min(amount, count - start) |> amount_with_step(step)
44624465
enumerable |> fun.() |> slice_exact(start, amount, step, count)
44634466

44644467
# TODO: Deprecate me in Elixir v1.18.
@@ -4473,8 +4476,7 @@ defmodule Enum do
44734476
end
44744477

44754478
{:ok, count, fun} when is_function(fun, 3) ->
4476-
amount = Kernel.min(amount, count - start)
4477-
amount = if step == 1, do: amount, else: div(amount - 1, step) + 1
4479+
amount = Kernel.min(amount, count - start) |> amount_with_step(step)
44784480
fun.(start, amount, step)
44794481

44804482
{:error, module} ->

lib/elixir/test/elixir/enum_test.exs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,16 @@ defmodule EnumTest do
11021102
[2, 1, 3]
11031103
end
11041104

1105+
test "slice on MapSets" do
1106+
assert MapSet.new(1..10) |> Enum.slice(0, 2) |> Enum.count() == 2
1107+
assert MapSet.new(1..3) |> Enum.slice(0, 10) |> Enum.count() == 3
1108+
assert MapSet.new(1..10) |> Enum.slice(0..1) |> Enum.count() == 2
1109+
assert MapSet.new(1..3) |> Enum.slice(0..10) |> Enum.count() == 3
1110+
1111+
assert MapSet.new(1..10) |> Enum.slice(0..4//2) |> Enum.count() == 3
1112+
assert MapSet.new(1..10) |> Enum.slice(0..5//2) |> Enum.count() == 3
1113+
end
1114+
11051115
test "sort/1" do
11061116
assert Enum.sort([5, 3, 2, 4, 1]) == [1, 2, 3, 4, 5]
11071117
end

0 commit comments

Comments
 (0)