@@ -2390,7 +2390,14 @@ defmodule Enum do
23902390 def random ( enumerable ) when is_list ( enumerable ) do
23912391 case length ( enumerable ) do
23922392 0 -> raise Enum.EmptyError
2393- length -> enumerable |> drop_list ( random_integer ( 0 , length - 1 ) ) |> hd ( )
2393+ length -> enumerable |> drop_list ( random_count ( length ) ) |> hd ( )
2394+ end
2395+ end
2396+
2397+ def random ( first .. _ // step = range ) do
2398+ case Range . size ( range ) do
2399+ 0 -> raise Enum.EmptyError
2400+ size -> first + random_count ( size ) * step
23942401 end
23952402 end
23962403
@@ -2401,14 +2408,14 @@ defmodule Enum do
24012408 [ ]
24022409
24032410 { :ok , count , fun } when is_function ( fun , 1 ) ->
2404- slice_list ( fun . ( enumerable ) , random_integer ( 0 , count - 1 ) , 1 , 1 )
2411+ slice_list ( fun . ( enumerable ) , random_count ( count ) , 1 , 1 )
24052412
24062413 # TODO: Deprecate me in Elixir v1.18.
24072414 { :ok , count , fun } when is_function ( fun , 2 ) ->
2408- fun . ( random_integer ( 0 , count - 1 ) , 1 )
2415+ fun . ( random_count ( count ) , 1 )
24092416
24102417 { :ok , count , fun } when is_function ( fun , 3 ) ->
2411- fun . ( random_integer ( 0 , count - 1 ) , 1 , 1 )
2418+ fun . ( random_count ( count ) , 1 , 1 )
24122419
24132420 { :error , _ } ->
24142421 take_random ( enumerable , 1 )
@@ -2420,6 +2427,10 @@ defmodule Enum do
24202427 end
24212428 end
24222429
2430+ defp random_count ( count ) do
2431+ :rand . uniform ( count ) - 1
2432+ end
2433+
24232434 @ doc """
24242435 Invokes `fun` for each element in the `enumerable` with the
24252436 accumulator.
@@ -3609,7 +3620,7 @@ defmodule Enum do
36093620 sample = Tuple . duplicate ( nil , count )
36103621
36113622 reducer = fn elem , { idx , sample } ->
3612- jdx = random_integer ( 0 , idx )
3623+ jdx = random_index ( idx )
36133624
36143625 cond do
36153626 idx < count ->
@@ -3630,7 +3641,7 @@ defmodule Enum do
36303641
36313642 def take_random ( enumerable , count ) when is_integer ( count ) and count >= 0 do
36323643 reducer = fn elem , { idx , sample } ->
3633- jdx = random_integer ( 0 , idx )
3644+ jdx = random_index ( idx )
36343645
36353646 cond do
36363647 idx < count ->
@@ -3666,6 +3677,9 @@ defmodule Enum do
36663677
36673678 defp take_random_list_one ( [ ] , current , _ ) , do: [ current ]
36683679
3680+ defp random_index ( 0 ) , do: 0
3681+ defp random_index ( idx ) , do: :rand . uniform ( idx + 1 ) - 1
3682+
36693683 @ doc """
36703684 Takes the elements from the beginning of the `enumerable` while `fun` returns
36713685 a truthy value.
@@ -4149,18 +4163,6 @@ defmodule Enum do
41494163 end )
41504164 end
41514165
4152- defp random_integer ( limit , limit ) when is_integer ( limit ) do
4153- limit
4154- end
4155-
4156- defp random_integer ( lower_limit , upper_limit ) when upper_limit < lower_limit do
4157- random_integer ( upper_limit , lower_limit )
4158- end
4159-
4160- defp random_integer ( lower_limit , upper_limit ) do
4161- lower_limit + :rand . uniform ( upper_limit - lower_limit + 1 ) - 1
4162- end
4163-
41644166 ## Implementations
41654167
41664168 ## all?/1
0 commit comments