1defprotocol Enumerable do 2 @moduledoc """ 3 Enumerable protocol used by `Enum` and `Stream` modules. 4 5 When you invoke a function in the `Enum` module, the first argument 6 is usually a collection that must implement this protocol. 7 For example, the expression `Enum.map([1, 2, 3], &(&1 * 2))` 8 invokes `Enumerable.reduce/3` to perform the reducing operation that 9 builds a mapped list by calling the mapping function `&(&1 * 2)` on 10 every element in the collection and consuming the element with an 11 accumulated list. 12 13 Internally, `Enum.map/2` is implemented as follows: 14 15 def map(enumerable, fun) do 16 reducer = fn x, acc -> {:cont, [fun.(x) | acc]} end 17 Enumerable.reduce(enumerable, {:cont, []}, reducer) |> elem(1) |> :lists.reverse() 18 end 19 20 Note that the user-supplied function is wrapped into a `t:reducer/0` function. 21 The `t:reducer/0` function must return a tagged tuple after each step, 22 as described in the `t:acc/0` type. At the end, `Enumerable.reduce/3` 23 returns `t:result/0`. 24 25 This protocol uses tagged tuples to exchange information between the 26 reducer function and the data type that implements the protocol. This 27 allows enumeration of resources, such as files, to be done efficiently 28 while also guaranteeing the resource will be closed at the end of the 29 enumeration. This protocol also allows suspension of the enumeration, 30 which is useful when interleaving between many enumerables is required 31 (as in the `zip/1` and `zip/2` functions). 32 33 This protocol requires four functions to be implemented, `reduce/3`, 34 `count/1`, `member?/2`, and `slice/1`. The core of the protocol is the 35 `reduce/3` function. All other functions exist as optimizations paths 36 for data structures that can implement certain properties in better 37 than linear time. 38 """ 39 40 @typedoc """ 41 The accumulator value for each step. 42 43 It must be a tagged tuple with one of the following "tags": 44 45 * `:cont` - the enumeration should continue 46 * `:halt` - the enumeration should halt immediately 47 * `:suspend` - the enumeration should be suspended immediately 48 49 Depending on the accumulator value, the result returned by 50 `Enumerable.reduce/3` will change. Please check the `t:result/0` 51 type documentation for more information. 52 53 In case a `t:reducer/0` function returns a `:suspend` accumulator, 54 it must be explicitly handled by the caller and never leak. 55 """ 56 @type acc :: {:cont, term} | {:halt, term} | {:suspend, term} 57 58 @typedoc """ 59 The reducer function. 60 61 Should be called with the `enumerable` element and the 62 accumulator contents. 63 64 Returns the accumulator for the next enumeration step. 65 """ 66 @type reducer :: (element :: term, current_acc :: acc -> updated_acc :: acc) 67 68 @typedoc """ 69 The result of the reduce operation. 70 71 It may be *done* when the enumeration is finished by reaching 72 its end, or *halted*/*suspended* when the enumeration was halted 73 or suspended by the tagged accumulator. 74 75 In case the tagged `:halt` accumulator is given, the `:halted` tuple 76 with the accumulator must be returned. Functions like `Enum.take_while/2` 77 use `:halt` underneath and can be used to test halting enumerables. 78 79 In case the tagged `:suspend` accumulator is given, the caller must 80 return the `:suspended` tuple with the accumulator and a continuation. 81 The caller is then responsible of managing the continuation and the 82 caller must always call the continuation, eventually halting or continuing 83 until the end. `Enum.zip/2` uses suspension, so it can be used to test 84 whether your implementation handles suspension correctly. You can also use 85 `Stream.zip/2` with `Enum.take_while/2` to test the combination of 86 `:suspend` with `:halt`. 87 """ 88 @type result :: 89 {:done, term} 90 | {:halted, term} 91 | {:suspended, term, continuation} 92 93 @typedoc """ 94 A partially applied reduce function. 95 96 The continuation is the closure returned as a result when 97 the enumeration is suspended. When invoked, it expects 98 a new accumulator and it returns the result. 99 100 A continuation can be trivially implemented as long as the reduce 101 function is defined in a tail recursive fashion. If the function 102 is tail recursive, all the state is passed as arguments, so 103 the continuation is the reducing function partially applied. 104 """ 105 @type continuation :: (acc -> result) 106 107 @typedoc """ 108 A slicing function that receives the initial position and the 109 number of elements in the slice. 110 111 The `start` position is a number `>= 0` and guaranteed to 112 exist in the `enumerable`. The length is a number `>= 1` in a way 113 that `start + length <= count`, where `count` is the maximum 114 amount of elements in the enumerable. 115 116 The function should return a non empty list where 117 the amount of elements is equal to `length`. 118 """ 119 @type slicing_fun :: (start :: non_neg_integer, length :: pos_integer -> [term()]) 120 121 @doc """ 122 Reduces the `enumerable` into an element. 123 124 Most of the operations in `Enum` are implemented in terms of reduce. 125 This function should apply the given `t:reducer/0` function to each 126 element in the `enumerable` and proceed as expected by the returned 127 accumulator. 128 129 See the documentation of the types `t:result/0` and `t:acc/0` for 130 more information. 131 132 ## Examples 133 134 As an example, here is the implementation of `reduce` for lists: 135 136 def reduce(_list, {:halt, acc}, _fun), do: {:halted, acc} 137 def reduce(list, {:suspend, acc}, fun), do: {:suspended, acc, &reduce(list, &1, fun)} 138 def reduce([], {:cont, acc}, _fun), do: {:done, acc} 139 def reduce([head | tail], {:cont, acc}, fun), do: reduce(tail, fun.(head, acc), fun) 140 141 """ 142 @spec reduce(t, acc, reducer) :: result 143 def reduce(enumerable, acc, fun) 144 145 @doc """ 146 Retrieves the number of elements in the `enumerable`. 147 148 It should return `{:ok, count}` if you can count the number of elements 149 in `enumerable` without traversing it. 150 151 Otherwise it should return `{:error, __MODULE__}` and a default algorithm 152 built on top of `reduce/3` that runs in linear time will be used. 153 """ 154 @spec count(t) :: {:ok, non_neg_integer} | {:error, module} 155 def count(enumerable) 156 157 @doc """ 158 Checks if an `element` exists within the `enumerable`. 159 160 It should return `{:ok, boolean}` if you can check the membership of a 161 given element in `enumerable` with `===/2` without traversing the whole 162 of it. 163 164 Otherwise it should return `{:error, __MODULE__}` and a default algorithm 165 built on top of `reduce/3` that runs in linear time will be used. 166 167 When called outside guards, the [`in`](`in/2`) and [`not in`](`in/2`) 168 operators work by using this function. 169 """ 170 @spec member?(t, term) :: {:ok, boolean} | {:error, module} 171 def member?(enumerable, element) 172 173 @doc """ 174 Returns a function that slices the data structure contiguously. 175 176 It should return `{:ok, size, slicing_fun}` if the `enumerable` has 177 a known bound and can access a position in the `enumerable` without 178 traversing all previous elements. 179 180 Otherwise it should return `{:error, __MODULE__}` and a default 181 algorithm built on top of `reduce/3` that runs in linear time will be 182 used. 183 184 ## Differences to `count/1` 185 186 The `size` value returned by this function is used for boundary checks, 187 therefore it is extremely important that this function only returns `:ok` 188 if retrieving the `size` of the `enumerable` is cheap, fast and takes constant 189 time. Otherwise the simplest of operations, such as `Enum.at(enumerable, 0)`, 190 will become too expensive. 191 192 On the other hand, the `count/1` function in this protocol should be 193 implemented whenever you can count the number of elements in the collection without 194 traversing it. 195 """ 196 @spec slice(t) :: 197 {:ok, size :: non_neg_integer(), slicing_fun()} 198 | {:error, module()} 199 def slice(enumerable) 200end 201 202defmodule Enum do 203 import Kernel, except: [max: 2, min: 2] 204 205 @moduledoc """ 206 Provides a set of algorithms to work with enumerables. 207 208 In Elixir, an enumerable is any data type that implements the 209 `Enumerable` protocol. `List`s (`[1, 2, 3]`), `Map`s (`%{foo: 1, bar: 2}`) 210 and `Range`s (`1..3`) are common data types used as enumerables: 211 212 iex> Enum.map([1, 2, 3], fn x -> x * 2 end) 213 [2, 4, 6] 214 215 iex> Enum.sum([1, 2, 3]) 216 6 217 218 iex> Enum.map(1..3, fn x -> x * 2 end) 219 [2, 4, 6] 220 221 iex> Enum.sum(1..3) 222 6 223 224 iex> map = %{"a" => 1, "b" => 2} 225 iex> Enum.map(map, fn {k, v} -> {k, v * 2} end) 226 [{"a", 2}, {"b", 4}] 227 228 However, many other enumerables exist in the language, such as `MapSet`s 229 and the data type returned by `File.stream!/3` which allows a file to be 230 traversed as if it was an enumerable. 231 232 The functions in this module work in linear time. This means that, the 233 time it takes to perform an operation grows at the same rate as the length 234 of the enumerable. This is expected on operations such as `Enum.map/2`. 235 After all, if we want to traverse every element on a list, the longer the 236 list, the more elements we need to traverse, and the longer it will take. 237 238 This linear behaviour should also be expected on operations like `count/1`, 239 `member?/2`, `at/2` and similar. While Elixir does allow data types to 240 provide performant variants for such operations, you should not expect it 241 to always be available, since the `Enum` module is meant to work with a 242 large variety of data types and not all data types can provide optimized 243 behaviour. 244 245 Finally, note the functions in the `Enum` module are eager: they will 246 traverse the enumerable as soon as they are invoked. This is particularly 247 dangerous when working with infinite enumerables. In such cases, you should 248 use the `Stream` module, which allows you to lazily express computations, 249 without traversing collections, and work with possibly infinite collections. 250 See the `Stream` module for examples and documentation. 251 """ 252 253 @compile :inline_list_funcs 254 255 @type t :: Enumerable.t() 256 @type acc :: any 257 @type element :: any 258 259 @typedoc "Zero-based index. It can also be a negative integer." 260 @type index :: integer 261 262 @type default :: any 263 264 require Stream.Reducers, as: R 265 266 defmacrop skip(acc) do 267 acc 268 end 269 270 defmacrop next(_, entry, acc) do 271 quote(do: [unquote(entry) | unquote(acc)]) 272 end 273 274 defmacrop acc(head, state, _) do 275 quote(do: {unquote(head), unquote(state)}) 276 end 277 278 defmacrop next_with_acc(_, entry, head, state, _) do 279 quote do 280 {[unquote(entry) | unquote(head)], unquote(state)} 281 end 282 end 283 284 @doc """ 285 Returns `true` if all elements in `enumerable` are truthy. 286 287 When an element has a falsy value (`false` or `nil`) iteration stops immediately 288 and `false` is returned. In all other cases `true` is returned. 289 290 ## Examples 291 292 iex> Enum.all?([1, 2, 3]) 293 true 294 295 iex> Enum.all?([1, nil, 3]) 296 false 297 298 iex> Enum.all?([]) 299 true 300 301 """ 302 @spec all?(t) :: boolean 303 def all?(enumerable) when is_list(enumerable) do 304 all_list(enumerable) 305 end 306 307 def all?(enumerable) do 308 Enumerable.reduce(enumerable, {:cont, true}, fn entry, _ -> 309 if entry, do: {:cont, true}, else: {:halt, false} 310 end) 311 |> elem(1) 312 end 313 314 @doc """ 315 Returns `true` if `fun.(element)` is truthy for all elements in `enumerable`. 316 317 Iterates over `enumerable` and invokes `fun` on each element. If `fun` ever 318 returns a falsy value (`false` or `nil`), iteration stops immediately and 319 `false` is returned. Otherwise, `true` is returned. 320 321 ## Examples 322 323 iex> Enum.all?([2, 4, 6], fn x -> rem(x, 2) == 0 end) 324 true 325 326 iex> Enum.all?([2, 3, 4], fn x -> rem(x, 2) == 0 end) 327 false 328 329 iex> Enum.all?([], fn _ -> nil end) 330 true 331 332 As the last example shows, `Enum.all?/2` returns `true` if `enumerable` is 333 empty, regardless of `fun`. In an empty enumerable there is no element for 334 which `fun` returns a falsy value, so the result must be `true`. This is a 335 well-defined logical argument for empty collections. 336 337 """ 338 @spec all?(t, (element -> as_boolean(term))) :: boolean 339 def all?(enumerable, fun) when is_list(enumerable) do 340 all_list(enumerable, fun) 341 end 342 343 def all?(enumerable, fun) do 344 Enumerable.reduce(enumerable, {:cont, true}, fn entry, _ -> 345 if fun.(entry), do: {:cont, true}, else: {:halt, false} 346 end) 347 |> elem(1) 348 end 349 350 @doc """ 351 Returns `true` if at least one element in `enumerable` is truthy. 352 353 When an element has a truthy value (neither `false` nor `nil`) iteration stops 354 immediately and `true` is returned. In all other cases `false` is returned. 355 356 ## Examples 357 358 iex> Enum.any?([false, false, false]) 359 false 360 361 iex> Enum.any?([false, true, false]) 362 true 363 364 iex> Enum.any?([]) 365 false 366 367 """ 368 @spec any?(t) :: boolean 369 def any?(enumerable) when is_list(enumerable) do 370 any_list(enumerable) 371 end 372 373 def any?(enumerable) do 374 Enumerable.reduce(enumerable, {:cont, false}, fn entry, _ -> 375 if entry, do: {:halt, true}, else: {:cont, false} 376 end) 377 |> elem(1) 378 end 379 380 @doc """ 381 Returns `true` if `fun.(element)` is truthy for at least one element in `enumerable`. 382 383 Iterates over the `enumerable` and invokes `fun` on each element. When an invocation 384 of `fun` returns a truthy value (neither `false` nor `nil`) iteration stops 385 immediately and `true` is returned. In all other cases `false` is returned. 386 387 ## Examples 388 389 iex> Enum.any?([2, 4, 6], fn x -> rem(x, 2) == 1 end) 390 false 391 392 iex> Enum.any?([2, 3, 4], fn x -> rem(x, 2) == 1 end) 393 true 394 395 iex> Enum.any?([], fn x -> x > 0 end) 396 false 397 398 """ 399 @spec any?(t, (element -> as_boolean(term))) :: boolean 400 def any?(enumerable, fun) when is_list(enumerable) do 401 any_list(enumerable, fun) 402 end 403 404 def any?(enumerable, fun) do 405 Enumerable.reduce(enumerable, {:cont, false}, fn entry, _ -> 406 if fun.(entry), do: {:halt, true}, else: {:cont, false} 407 end) 408 |> elem(1) 409 end 410 411 @doc """ 412 Finds the element at the given `index` (zero-based). 413 414 Returns `default` if `index` is out of bounds. 415 416 A negative `index` can be passed, which means the `enumerable` is 417 enumerated once and the `index` is counted from the end (for example, 418 `-1` finds the last element). 419 420 ## Examples 421 422 iex> Enum.at([2, 4, 6], 0) 423 2 424 425 iex> Enum.at([2, 4, 6], 2) 426 6 427 428 iex> Enum.at([2, 4, 6], 4) 429 nil 430 431 iex> Enum.at([2, 4, 6], 4, :none) 432 :none 433 434 """ 435 @spec at(t, index, default) :: element | default 436 def at(enumerable, index, default \\ nil) when is_integer(index) do 437 case slice_any(enumerable, index, 1) do 438 [value] -> value 439 [] -> default 440 end 441 end 442 443 @doc false 444 @deprecated "Use Enum.chunk_every/2 instead" 445 def chunk(enumerable, count), do: chunk(enumerable, count, count, nil) 446 447 @doc false 448 @deprecated "Use Enum.chunk_every/3 instead" 449 def chunk(enum, n, step) do 450 chunk_every(enum, n, step, :discard) 451 end 452 453 @doc false 454 @deprecated "Use Enum.chunk_every/4 instead" 455 def chunk(enumerable, count, step, leftover) do 456 chunk_every(enumerable, count, step, leftover || :discard) 457 end 458 459 @doc """ 460 Shortcut to `chunk_every(enumerable, count, count)`. 461 """ 462 @doc since: "1.5.0" 463 @spec chunk_every(t, pos_integer) :: [list] 464 def chunk_every(enumerable, count), do: chunk_every(enumerable, count, count, []) 465 466 @doc """ 467 Returns list of lists containing `count` elements each, where 468 each new chunk starts `step` elements into the `enumerable`. 469 470 `step` is optional and, if not passed, defaults to `count`, i.e. 471 chunks do not overlap. 472 473 If the last chunk does not have `count` elements to fill the chunk, 474 elements are taken from `leftover` to fill in the chunk. If `leftover` 475 does not have enough elements to fill the chunk, then a partial chunk 476 is returned with less than `count` elements. 477 478 If `:discard` is given in `leftover`, the last chunk is discarded 479 unless it has exactly `count` elements. 480 481 ## Examples 482 483 iex> Enum.chunk_every([1, 2, 3, 4, 5, 6], 2) 484 [[1, 2], [3, 4], [5, 6]] 485 486 iex> Enum.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, :discard) 487 [[1, 2, 3], [3, 4, 5]] 488 489 iex> Enum.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, [7]) 490 [[1, 2, 3], [3, 4, 5], [5, 6, 7]] 491 492 iex> Enum.chunk_every([1, 2, 3, 4], 3, 3, []) 493 [[1, 2, 3], [4]] 494 495 iex> Enum.chunk_every([1, 2, 3, 4], 10) 496 [[1, 2, 3, 4]] 497 498 iex> Enum.chunk_every([1, 2, 3, 4, 5], 2, 3, []) 499 [[1, 2], [4, 5]] 500 501 """ 502 @doc since: "1.5.0" 503 @spec chunk_every(t, pos_integer, pos_integer, t | :discard) :: [list] 504 def chunk_every(enumerable, count, step, leftover \\ []) 505 when is_integer(count) and count > 0 and is_integer(step) and step > 0 do 506 R.chunk_every(&chunk_while/4, enumerable, count, step, leftover) 507 end 508 509 @doc """ 510 Chunks the `enumerable` with fine grained control when every chunk is emitted. 511 512 `chunk_fun` receives the current element and the accumulator and must return: 513 514 * `{:cont, chunk, acc}` to emit a chunk and continue with the accumulator 515 * `{:cont, acc}` to not emit any chunk and continue with the accumulator 516 * `{:halt, acc}` to halt chunking over the `enumerable`. 517 518 `after_fun` is invoked with the final accumulator when iteration is 519 finished (or `halt`ed) to handle any trailing elements that were returned 520 as part of an accumulator, but were not emitted as a chunk by `chunk_fun`. 521 It must return: 522 523 * `{:cont, chunk, acc}` to emit a chunk. The chunk will be appended to the 524 list of already emitted chunks. 525 * `{:cont, acc}` to not emit a chunk 526 527 The `acc` in `after_fun` is required in order to mirror the tuple format 528 from `chunk_fun` but it will be discarded since the traversal is complete. 529 530 Returns a list of emitted chunks. 531 532 ## Examples 533 534 iex> chunk_fun = fn element, acc -> 535 ...> if rem(element, 2) == 0 do 536 ...> {:cont, Enum.reverse([element | acc]), []} 537 ...> else 538 ...> {:cont, [element | acc]} 539 ...> end 540 ...> end 541 iex> after_fun = fn 542 ...> [] -> {:cont, []} 543 ...> acc -> {:cont, Enum.reverse(acc), []} 544 ...> end 545 iex> Enum.chunk_while(1..10, [], chunk_fun, after_fun) 546 [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] 547 iex> Enum.chunk_while([1, 2, 3, 5, 7], [], chunk_fun, after_fun) 548 [[1, 2], [3, 5, 7]] 549 550 """ 551 @doc since: "1.5.0" 552 @spec chunk_while( 553 t, 554 acc, 555 (element, acc -> {:cont, chunk, acc} | {:cont, acc} | {:halt, acc}), 556 (acc -> {:cont, chunk, acc} | {:cont, acc}) 557 ) :: Enumerable.t() 558 when chunk: any 559 def chunk_while(enumerable, acc, chunk_fun, after_fun) do 560 {_, {res, acc}} = 561 Enumerable.reduce(enumerable, {:cont, {[], acc}}, fn entry, {buffer, acc} -> 562 case chunk_fun.(entry, acc) do 563 {:cont, chunk, acc} -> {:cont, {[chunk | buffer], acc}} 564 {:cont, acc} -> {:cont, {buffer, acc}} 565 {:halt, acc} -> {:halt, {buffer, acc}} 566 end 567 end) 568 569 case after_fun.(acc) do 570 {:cont, _acc} -> :lists.reverse(res) 571 {:cont, chunk, _acc} -> :lists.reverse([chunk | res]) 572 end 573 end 574 575 @doc """ 576 Splits enumerable on every element for which `fun` returns a new 577 value. 578 579 Returns a list of lists. 580 581 ## Examples 582 583 iex> Enum.chunk_by([1, 2, 2, 3, 4, 4, 6, 7, 7], &(rem(&1, 2) == 1)) 584 [[1], [2, 2], [3], [4, 4, 6], [7, 7]] 585 586 """ 587 @spec chunk_by(t, (element -> any)) :: [list] 588 def chunk_by(enumerable, fun) do 589 R.chunk_by(&chunk_while/4, enumerable, fun) 590 end 591 592 @doc """ 593 Given an enumerable of enumerables, concatenates the `enumerables` into 594 a single list. 595 596 ## Examples 597 598 iex> Enum.concat([1..3, 4..6, 7..9]) 599 [1, 2, 3, 4, 5, 6, 7, 8, 9] 600 601 iex> Enum.concat([[1, [2], 3], [4], [5, 6]]) 602 [1, [2], 3, 4, 5, 6] 603 604 """ 605 @spec concat(t) :: t 606 def concat(enumerables) 607 608 def concat(list) when is_list(list) do 609 concat_list(list) 610 end 611 612 def concat(enums) do 613 concat_enum(enums) 614 end 615 616 @doc """ 617 Concatenates the enumerable on the `right` with the enumerable on the 618 `left`. 619 620 This function produces the same result as the `Kernel.++/2` operator 621 for lists. 622 623 ## Examples 624 625 iex> Enum.concat(1..3, 4..6) 626 [1, 2, 3, 4, 5, 6] 627 628 iex> Enum.concat([1, 2, 3], [4, 5, 6]) 629 [1, 2, 3, 4, 5, 6] 630 631 """ 632 @spec concat(t, t) :: t 633 def concat(left, right) when is_list(left) and is_list(right) do 634 left ++ right 635 end 636 637 def concat(left, right) do 638 concat_enum([left, right]) 639 end 640 641 @doc """ 642 Returns the size of the `enumerable`. 643 644 ## Examples 645 646 iex> Enum.count([1, 2, 3]) 647 3 648 649 """ 650 @spec count(t) :: non_neg_integer 651 def count(enumerable) when is_list(enumerable) do 652 length(enumerable) 653 end 654 655 def count(enumerable) do 656 case Enumerable.count(enumerable) do 657 {:ok, value} when is_integer(value) -> 658 value 659 660 {:error, module} -> 661 enumerable |> module.reduce({:cont, 0}, fn _, acc -> {:cont, acc + 1} end) |> elem(1) 662 end 663 end 664 665 @doc """ 666 Returns the count of elements in the `enumerable` for which `fun` returns 667 a truthy value. 668 669 ## Examples 670 671 iex> Enum.count([1, 2, 3, 4, 5], fn x -> rem(x, 2) == 0 end) 672 2 673 674 """ 675 @spec count(t, (element -> as_boolean(term))) :: non_neg_integer 676 def count(enumerable, fun) do 677 reduce(enumerable, 0, fn entry, acc -> 678 if(fun.(entry), do: acc + 1, else: acc) 679 end) 680 end 681 682 @doc """ 683 Counts the enumerable stopping at `limit`. 684 685 This is useful for checking certain properties of the count of an enumerable 686 without having to actually count the entire enumerable. For example, if you 687 wanted to check that the count was exactly, at least, or more than a value. 688 689 If the enumerable implements `c:Enumerable.count/1`, the enumerable is 690 not traversed and we return the lower of the two numbers. To force 691 enumeration, use `count_until/3` with `fn _ -> true end` as the second 692 argument. 693 694 ## Examples 695 696 iex> Enum.count_until(1..20, 5) 697 5 698 iex> Enum.count_until(1..20, 50) 699 20 700 iex> Enum.count_until(1..10, 10) == 10 # At least 10 701 true 702 iex> Enum.count_until(1..11, 10 + 1) > 10 # More than 10 703 true 704 iex> Enum.count_until(1..5, 10) < 10 # Less than 10 705 true 706 iex> Enum.count_until(1..10, 10 + 1) == 10 # Exactly ten 707 true 708 709 """ 710 @doc since: "1.12.0" 711 @spec count_until(t, pos_integer) :: non_neg_integer 712 def count_until(enumerable, limit) when is_integer(limit) and limit > 0 do 713 stop_at = limit - 1 714 715 case Enumerable.count(enumerable) do 716 {:ok, value} -> 717 Kernel.min(value, limit) 718 719 {:error, module} -> 720 enumerable 721 |> module.reduce( 722 {:cont, 0}, 723 fn 724 _, ^stop_at -> 725 {:halt, limit} 726 727 _, acc -> 728 {:cont, acc + 1} 729 end 730 ) 731 |> elem(1) 732 end 733 end 734 735 @doc """ 736 Counts the elements in the enumerable for which `fun` returns a truthy value, stopping at `limit`. 737 738 See `count/2` and `count_until/3` for more information. 739 740 ## Examples 741 742 iex> Enum.count_until(1..20, fn x -> rem(x, 2) == 0 end, 7) 743 7 744 iex> Enum.count_until(1..20, fn x -> rem(x, 2) == 0 end, 11) 745 10 746 """ 747 @doc since: "1.12.0" 748 @spec count_until(t, (element -> as_boolean(term)), pos_integer) :: non_neg_integer 749 def count_until(enumerable, fun, limit) when is_integer(limit) and limit > 0 do 750 stop_at = limit - 1 751 752 Enumerable.reduce(enumerable, {:cont, 0}, fn 753 entry, ^stop_at -> 754 if fun.(entry) do 755 {:halt, limit} 756 else 757 {:cont, stop_at} 758 end 759 760 entry, acc -> 761 if fun.(entry) do 762 {:cont, acc + 1} 763 else 764 {:cont, acc} 765 end 766 end) 767 |> elem(1) 768 end 769 770 @doc """ 771 Enumerates the `enumerable`, returning a list where all consecutive 772 duplicated elements are collapsed to a single element. 773 774 Elements are compared using `===/2`. 775 776 If you want to remove all duplicated elements, regardless of order, 777 see `uniq/1`. 778 779 ## Examples 780 781 iex> Enum.dedup([1, 2, 3, 3, 2, 1]) 782 [1, 2, 3, 2, 1] 783 784 iex> Enum.dedup([1, 1, 2, 2.0, :three, :three]) 785 [1, 2, 2.0, :three] 786 787 """ 788 @spec dedup(t) :: list 789 def dedup(enumerable) when is_list(enumerable) do 790 dedup_list(enumerable, []) |> :lists.reverse() 791 end 792 793 def dedup(enumerable) do 794 Enum.reduce(enumerable, [], fn x, acc -> 795 case acc do 796 [^x | _] -> acc 797 _ -> [x | acc] 798 end 799 end) 800 |> :lists.reverse() 801 end 802 803 @doc """ 804 Enumerates the `enumerable`, returning a list where all consecutive 805 duplicated elements are collapsed to a single element. 806 807 The function `fun` maps every element to a term which is used to 808 determine if two elements are duplicates. 809 810 ## Examples 811 812 iex> Enum.dedup_by([{1, :a}, {2, :b}, {2, :c}, {1, :a}], fn {x, _} -> x end) 813 [{1, :a}, {2, :b}, {1, :a}] 814 815 iex> Enum.dedup_by([5, 1, 2, 3, 2, 1], fn x -> x > 2 end) 816 [5, 1, 3, 2] 817 818 """ 819 @spec dedup_by(t, (element -> term)) :: list 820 def dedup_by(enumerable, fun) do 821 {list, _} = reduce(enumerable, {[], []}, R.dedup(fun)) 822 :lists.reverse(list) 823 end 824 825 @doc """ 826 Drops the `amount` of elements from the `enumerable`. 827 828 If a negative `amount` is given, the `amount` of last values will be dropped. 829 The `enumerable` will be enumerated once to retrieve the proper index and 830 the remaining calculation is performed from the end. 831 832 ## Examples 833 834 iex> Enum.drop([1, 2, 3], 2) 835 [3] 836 837 iex> Enum.drop([1, 2, 3], 10) 838 [] 839 840 iex> Enum.drop([1, 2, 3], 0) 841 [1, 2, 3] 842 843 iex> Enum.drop([1, 2, 3], -1) 844 [1, 2] 845 846 """ 847 @spec drop(t, integer) :: list 848 def drop(enumerable, amount) 849 when is_list(enumerable) and is_integer(amount) and amount >= 0 do 850 drop_list(enumerable, amount) 851 end 852 853 def drop(enumerable, amount) when is_integer(amount) and amount >= 0 do 854 {result, _} = reduce(enumerable, {[], amount}, R.drop()) 855 if is_list(result), do: :lists.reverse(result), else: [] 856 end 857 858 def drop(enumerable, amount) when is_integer(amount) and amount < 0 do 859 {count, fun} = slice_count_and_fun(enumerable) 860 amount = Kernel.min(amount + count, count) 861 862 if amount > 0 do 863 fun.(0, amount) 864 else 865 [] 866 end 867 end 868 869 @doc """ 870 Returns a list of every `nth` element in the `enumerable` dropped, 871 starting with the first element. 872 873 The first element is always dropped, unless `nth` is 0. 874 875 The second argument specifying every `nth` element must be a non-negative 876 integer. 877 878 ## Examples 879 880 iex> Enum.drop_every(1..10, 2) 881 [2, 4, 6, 8, 10] 882 883 iex> Enum.drop_every(1..10, 0) 884 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 885 886 iex> Enum.drop_every([1, 2, 3], 1) 887 [] 888 889 """ 890 @spec drop_every(t, non_neg_integer) :: list 891 def drop_every(enumerable, nth) 892 893 def drop_every(_enumerable, 1), do: [] 894 def drop_every(enumerable, 0), do: to_list(enumerable) 895 def drop_every([], nth) when is_integer(nth), do: [] 896 897 def drop_every(enumerable, nth) when is_integer(nth) and nth > 1 do 898 {res, _} = reduce(enumerable, {[], :first}, R.drop_every(nth)) 899 :lists.reverse(res) 900 end 901 902 @doc """ 903 Drops elements at the beginning of the `enumerable` while `fun` returns a 904 truthy value. 905 906 ## Examples 907 908 iex> Enum.drop_while([1, 2, 3, 2, 1], fn x -> x < 3 end) 909 [3, 2, 1] 910 911 """ 912 @spec drop_while(t, (element -> as_boolean(term))) :: list 913 def drop_while(enumerable, fun) when is_list(enumerable) do 914 drop_while_list(enumerable, fun) 915 end 916 917 def drop_while(enumerable, fun) do 918 {res, _} = reduce(enumerable, {[], true}, R.drop_while(fun)) 919 :lists.reverse(res) 920 end 921 922 @doc """ 923 Invokes the given `fun` for each element in the `enumerable`. 924 925 Returns `:ok`. 926 927 ## Examples 928 929 Enum.each(["some", "example"], fn x -> IO.puts(x) end) 930 "some" 931 "example" 932 #=> :ok 933 934 """ 935 @spec each(t, (element -> any)) :: :ok 936 def each(enumerable, fun) when is_list(enumerable) do 937 :lists.foreach(fun, enumerable) 938 end 939 940 def each(enumerable, fun) do 941 reduce(enumerable, nil, fn entry, _ -> 942 fun.(entry) 943 nil 944 end) 945 946 :ok 947 end 948 949 @doc """ 950 Determines if the `enumerable` is empty. 951 952 Returns `true` if `enumerable` is empty, otherwise `false`. 953 954 ## Examples 955 956 iex> Enum.empty?([]) 957 true 958 959 iex> Enum.empty?([1, 2, 3]) 960 false 961 962 """ 963 @spec empty?(t) :: boolean 964 def empty?(enumerable) when is_list(enumerable) do 965 enumerable == [] 966 end 967 968 def empty?(enumerable) do 969 case Enumerable.slice(enumerable) do 970 {:ok, value, _} -> 971 value == 0 972 973 {:error, module} -> 974 enumerable 975 |> module.reduce({:cont, true}, fn _, _ -> {:halt, false} end) 976 |> elem(1) 977 end 978 end 979 980 @doc """ 981 Finds the element at the given `index` (zero-based). 982 983 Returns `{:ok, element}` if found, otherwise `:error`. 984 985 A negative `index` can be passed, which means the `enumerable` is 986 enumerated once and the `index` is counted from the end (for example, 987 `-1` fetches the last element). 988 989 ## Examples 990 991 iex> Enum.fetch([2, 4, 6], 0) 992 {:ok, 2} 993 994 iex> Enum.fetch([2, 4, 6], -3) 995 {:ok, 2} 996 997 iex> Enum.fetch([2, 4, 6], 2) 998 {:ok, 6} 999 1000 iex> Enum.fetch([2, 4, 6], 4) 1001 :error 1002 1003 """ 1004 @spec fetch(t, index) :: {:ok, element} | :error 1005 def fetch(enumerable, index) when is_integer(index) do 1006 case slice_any(enumerable, index, 1) do 1007 [value] -> {:ok, value} 1008 [] -> :error 1009 end 1010 end 1011 1012 @doc """ 1013 Finds the element at the given `index` (zero-based). 1014 1015 Raises `OutOfBoundsError` if the given `index` is outside the range of 1016 the `enumerable`. 1017 1018 ## Examples 1019 1020 iex> Enum.fetch!([2, 4, 6], 0) 1021 2 1022 1023 iex> Enum.fetch!([2, 4, 6], 2) 1024 6 1025 1026 iex> Enum.fetch!([2, 4, 6], 4) 1027 ** (Enum.OutOfBoundsError) out of bounds error 1028 1029 """ 1030 @spec fetch!(t, index) :: element 1031 def fetch!(enumerable, index) when is_integer(index) do 1032 case slice_any(enumerable, index, 1) do 1033 [value] -> value 1034 [] -> raise Enum.OutOfBoundsError 1035 end 1036 end 1037 1038 @doc """ 1039 Filters the `enumerable`, i.e. returns only those elements 1040 for which `fun` returns a truthy value. 1041 1042 See also `reject/2` which discards all elements where the 1043 function returns a truthy value. 1044 1045 ## Examples 1046 1047 iex> Enum.filter([1, 2, 3], fn x -> rem(x, 2) == 0 end) 1048 [2] 1049 1050 Keep in mind that `filter` is not capable of filtering and 1051 transforming an element at the same time. If you would like 1052 to do so, consider using `flat_map/2`. For example, if you 1053 want to convert all strings that represent an integer and 1054 discard the invalid one in one pass: 1055 1056 strings = ["1234", "abc", "12ab"] 1057 1058 Enum.flat_map(strings, fn string -> 1059 case Integer.parse(string) do 1060 # transform to integer 1061 {int, _rest} -> [int] 1062 # skip the value 1063 :error -> [] 1064 end 1065 end) 1066 1067 """ 1068 @spec filter(t, (element -> as_boolean(term))) :: list 1069 def filter(enumerable, fun) when is_list(enumerable) do 1070 filter_list(enumerable, fun) 1071 end 1072 1073 def filter(enumerable, fun) do 1074 reduce(enumerable, [], R.filter(fun)) |> :lists.reverse() 1075 end 1076 1077 @doc false 1078 @deprecated "Use Enum.filter/2 + Enum.map/2 or for comprehensions instead" 1079 def filter_map(enumerable, filter, mapper) when is_list(enumerable) do 1080 for element <- enumerable, filter.(element), do: mapper.(element) 1081 end 1082 1083 def filter_map(enumerable, filter, mapper) do 1084 enumerable 1085 |> reduce([], R.filter_map(filter, mapper)) 1086 |> :lists.reverse() 1087 end 1088 1089 @doc """ 1090 Returns the first element for which `fun` returns a truthy value. 1091 If no such element is found, returns `default`. 1092 1093 ## Examples 1094 1095 iex> Enum.find([2, 3, 4], fn x -> rem(x, 2) == 1 end) 1096 3 1097 1098 iex> Enum.find([2, 4, 6], fn x -> rem(x, 2) == 1 end) 1099 nil 1100 iex> Enum.find([2, 4, 6], 0, fn x -> rem(x, 2) == 1 end) 1101 0 1102 1103 """ 1104 @spec find(t, default, (element -> any)) :: element | default 1105 def find(enumerable, default \\ nil, fun) 1106 1107 def find(enumerable, default, fun) when is_list(enumerable) do 1108 find_list(enumerable, default, fun) 1109 end 1110 1111 def find(enumerable, default, fun) do 1112 Enumerable.reduce(enumerable, {:cont, default}, fn entry, default -> 1113 if fun.(entry), do: {:halt, entry}, else: {:cont, default} 1114 end) 1115 |> elem(1) 1116 end 1117 1118 @doc """ 1119 Similar to `find/3`, but returns the index (zero-based) 1120 of the element instead of the element itself. 1121 1122 ## Examples 1123 1124 iex> Enum.find_index([2, 4, 6], fn x -> rem(x, 2) == 1 end) 1125 nil 1126 1127 iex> Enum.find_index([2, 3, 4], fn x -> rem(x, 2) == 1 end) 1128 1 1129 1130 """ 1131 @spec find_index(t, (element -> any)) :: non_neg_integer | nil 1132 def find_index(enumerable, fun) when is_list(enumerable) do 1133 find_index_list(enumerable, 0, fun) 1134 end 1135 1136 def find_index(enumerable, fun) do 1137 result = 1138 Enumerable.reduce(enumerable, {:cont, {:not_found, 0}}, fn entry, {_, index} -> 1139 if fun.(entry), do: {:halt, {:found, index}}, else: {:cont, {:not_found, index + 1}} 1140 end) 1141 1142 case elem(result, 1) do 1143 {:found, index} -> index 1144 {:not_found, _} -> nil 1145 end 1146 end 1147 1148 @doc """ 1149 Similar to `find/3`, but returns the value of the function 1150 invocation instead of the element itself. 1151 1152 The return value is considered to be found when the result is truthy 1153 (neither `nil` nor `false`). 1154 1155 ## Examples 1156 1157 iex> Enum.find_value([2, 3, 4], fn x -> 1158 ...> if x > 2, do: x * x 1159 ...> end) 1160 9 1161 1162 iex> Enum.find_value([2, 4, 6], fn x -> rem(x, 2) == 1 end) 1163 nil 1164 1165 iex> Enum.find_value([2, 3, 4], fn x -> rem(x, 2) == 1 end) 1166 true 1167 1168 iex> Enum.find_value([1, 2, 3], "no bools!", &is_boolean/1) 1169 "no bools!" 1170 1171 """ 1172 @spec find_value(t, any, (element -> any)) :: any | nil 1173 def find_value(enumerable, default \\ nil, fun) 1174 1175 def find_value(enumerable, default, fun) when is_list(enumerable) do 1176 find_value_list(enumerable, default, fun) 1177 end 1178 1179 def find_value(enumerable, default, fun) do 1180 Enumerable.reduce(enumerable, {:cont, default}, fn entry, default -> 1181 fun_entry = fun.(entry) 1182 if fun_entry, do: {:halt, fun_entry}, else: {:cont, default} 1183 end) 1184 |> elem(1) 1185 end 1186 1187 @doc """ 1188 Maps the given `fun` over `enumerable` and flattens the result. 1189 1190 This function returns a new enumerable built by appending the result of invoking `fun` 1191 on each element of `enumerable` together; conceptually, this is similar to a 1192 combination of `map/2` and `concat/1`. 1193 1194 ## Examples 1195 1196 iex> Enum.flat_map([:a, :b, :c], fn x -> [x, x] end) 1197 [:a, :a, :b, :b, :c, :c] 1198 1199 iex> Enum.flat_map([{1, 3}, {4, 6}], fn {x, y} -> x..y end) 1200 [1, 2, 3, 4, 5, 6] 1201 1202 iex> Enum.flat_map([:a, :b, :c], fn x -> [[x]] end) 1203 [[:a], [:b], [:c]] 1204 1205 """ 1206 @spec flat_map(t, (element -> t)) :: list 1207 def flat_map(enumerable, fun) when is_list(enumerable) do 1208 flat_map_list(enumerable, fun) 1209 end 1210 1211 def flat_map(enumerable, fun) do 1212 reduce(enumerable, [], fn entry, acc -> 1213 case fun.(entry) do 1214 list when is_list(list) -> [list | acc] 1215 other -> [to_list(other) | acc] 1216 end 1217 end) 1218 |> flat_reverse([]) 1219 end 1220 1221 defp flat_reverse([h | t], acc), do: flat_reverse(t, h ++ acc) 1222 defp flat_reverse([], acc), do: acc 1223 1224 @doc """ 1225 Maps and reduces an `enumerable`, flattening the given results (only one level deep). 1226 1227 It expects an accumulator and a function that receives each enumerable 1228 element, and must return a tuple containing a new enumerable (often a list) 1229 with the new accumulator or a tuple with `:halt` as first element and 1230 the accumulator as second. 1231 1232 ## Examples 1233 1234 iex> enumerable = 1..100 1235 iex> n = 3 1236 iex> Enum.flat_map_reduce(enumerable, 0, fn x, acc -> 1237 ...> if acc < n, do: {[x], acc + 1}, else: {:halt, acc} 1238 ...> end) 1239 {[1, 2, 3], 3} 1240 1241 iex> Enum.flat_map_reduce(1..5, 0, fn x, acc -> {[[x]], acc + x} end) 1242 {[[1], [2], [3], [4], [5]], 15} 1243 1244 """ 1245 @spec flat_map_reduce(t, acc, fun) :: {[any], acc} 1246 when fun: (element, acc -> {t, acc} | {:halt, acc}) 1247 def flat_map_reduce(enumerable, acc, fun) do 1248 {_, {list, acc}} = 1249 Enumerable.reduce(enumerable, {:cont, {[], acc}}, fn entry, {list, acc} -> 1250 case fun.(entry, acc) do 1251 {:halt, acc} -> 1252 {:halt, {list, acc}} 1253 1254 {[], acc} -> 1255 {:cont, {list, acc}} 1256 1257 {[entry], acc} -> 1258 {:cont, {[entry | list], acc}} 1259 1260 {entries, acc} -> 1261 {:cont, {reduce(entries, list, &[&1 | &2]), acc}} 1262 end 1263 end) 1264 1265 {:lists.reverse(list), acc} 1266 end 1267 1268 @doc """ 1269 Returns a map with keys as unique elements of `enumerable` and values 1270 as the count of every element. 1271 1272 ## Examples 1273 1274 iex> Enum.frequencies(~w{ant buffalo ant ant buffalo dingo}) 1275 %{"ant" => 3, "buffalo" => 2, "dingo" => 1} 1276 1277 """ 1278 @doc since: "1.10.0" 1279 @spec frequencies(t) :: map 1280 def frequencies(enumerable) do 1281 reduce(enumerable, %{}, fn key, acc -> 1282 case acc do 1283 %{^key => value} -> %{acc | key => value + 1} 1284 %{} -> Map.put(acc, key, 1) 1285 end 1286 end) 1287 end 1288 1289 @doc """ 1290 Returns a map with keys as unique elements given by `key_fun` and values 1291 as the count of every element. 1292 1293 ## Examples 1294 1295 iex> Enum.frequencies_by(~w{aa aA bb cc}, &String.downcase/1) 1296 %{"aa" => 2, "bb" => 1, "cc" => 1} 1297 1298 iex> Enum.frequencies_by(~w{aaa aA bbb cc c}, &String.length/1) 1299 %{3 => 2, 2 => 2, 1 => 1} 1300 1301 """ 1302 @doc since: "1.10.0" 1303 @spec frequencies_by(t, (element -> any)) :: map 1304 def frequencies_by(enumerable, key_fun) when is_function(key_fun) do 1305 reduce(enumerable, %{}, fn entry, acc -> 1306 key = key_fun.(entry) 1307 1308 case acc do 1309 %{^key => value} -> %{acc | key => value + 1} 1310 %{} -> Map.put(acc, key, 1) 1311 end 1312 end) 1313 end 1314 1315 @doc """ 1316 Splits the `enumerable` into groups based on `key_fun`. 1317 1318 The result is a map where each key is given by `key_fun` 1319 and each value is a list of elements given by `value_fun`. 1320 The order of elements within each list is preserved from the `enumerable`. 1321 However, like all maps, the resulting map is unordered. 1322 1323 ## Examples 1324 1325 iex> Enum.group_by(~w{ant buffalo cat dingo}, &String.length/1) 1326 %{3 => ["ant", "cat"], 5 => ["dingo"], 7 => ["buffalo"]} 1327 1328 iex> Enum.group_by(~w{ant buffalo cat dingo}, &String.length/1, &String.first/1) 1329 %{3 => ["a", "c"], 5 => ["d"], 7 => ["b"]} 1330 1331 """ 1332 @spec group_by(t, (element -> any), (element -> any)) :: map 1333 def group_by(enumerable, key_fun, value_fun \\ fn x -> x end) 1334 1335 def group_by(enumerable, key_fun, value_fun) when is_function(key_fun) do 1336 reduce(reverse(enumerable), %{}, fn entry, acc -> 1337 key = key_fun.(entry) 1338 value = value_fun.(entry) 1339 1340 case acc do 1341 %{^key => existing} -> %{acc | key => [value | existing]} 1342 %{} -> Map.put(acc, key, [value]) 1343 end 1344 end) 1345 end 1346 1347 def group_by(enumerable, dict, fun) do 1348 IO.warn( 1349 "Enum.group_by/3 with a map/dictionary as second element is deprecated. " <> 1350 "A map is used by default and it is no longer required to pass one to this function" 1351 ) 1352 1353 # Avoid warnings about Dict 1354 dict_module = Dict 1355 1356 reduce(reverse(enumerable), dict, fn entry, categories -> 1357 dict_module.update(categories, fun.(entry), [entry], &[entry | &1]) 1358 end) 1359 end 1360 1361 @doc """ 1362 Intersperses `separator` between each element of the enumeration. 1363 1364 ## Examples 1365 1366 iex> Enum.intersperse([1, 2, 3], 0) 1367 [1, 0, 2, 0, 3] 1368 1369 iex> Enum.intersperse([1], 0) 1370 [1] 1371 1372 iex> Enum.intersperse([], 0) 1373 [] 1374 1375 """ 1376 @spec intersperse(t, element) :: list 1377 def intersperse(enumerable, separator) when is_list(enumerable) do 1378 case enumerable do 1379 [] -> [] 1380 list -> intersperse_non_empty_list(list, separator) 1381 end 1382 end 1383 1384 def intersperse(enumerable, separator) do 1385 list = 1386 enumerable 1387 |> reduce([], fn x, acc -> [x, separator | acc] end) 1388 |> :lists.reverse() 1389 1390 # Head is a superfluous separator 1391 case list do 1392 [] -> [] 1393 [_ | t] -> t 1394 end 1395 end 1396 1397 @doc """ 1398 Inserts the given `enumerable` into a `collectable`. 1399 1400 Note that passing a non-empty list as the `collectable` is deprecated. 1401 If you're collecting into a non-empty keyword list, consider using 1402 `Keyword.merge(collectable, Enum.to_list(enumerable))`. If you're collecting 1403 into a non-empty list, consider something like `Enum.to_list(enumerable) ++ collectable`. 1404 1405 ## Examples 1406 1407 iex> Enum.into([1, 2], []) 1408 [1, 2] 1409 1410 iex> Enum.into([a: 1, b: 2], %{}) 1411 %{a: 1, b: 2} 1412 1413 iex> Enum.into(%{a: 1}, %{b: 2}) 1414 %{a: 1, b: 2} 1415 1416 iex> Enum.into([a: 1, a: 2], %{}) 1417 %{a: 2} 1418 1419 """ 1420 @spec into(Enumerable.t(), Collectable.t()) :: Collectable.t() 1421 def into(enumerable, collectable) 1422 1423 def into(enumerable, []) do 1424 to_list(enumerable) 1425 end 1426 1427 def into(%_{} = enumerable, collectable) do 1428 into_protocol(enumerable, collectable) 1429 end 1430 1431 def into(enumerable, %_{} = collectable) do 1432 into_protocol(enumerable, collectable) 1433 end 1434 1435 def into(enumerable, %{} = collectable) do 1436 if map_size(collectable) == 0 do 1437 into_map(enumerable) 1438 else 1439 into_map(enumerable, collectable) 1440 end 1441 end 1442 1443 def into(enumerable, collectable) do 1444 into_protocol(enumerable, collectable) 1445 end 1446 1447 defp into_map(%{} = enumerable), do: enumerable 1448 defp into_map(enumerable) when is_list(enumerable), do: :maps.from_list(enumerable) 1449 defp into_map(enumerable), do: enumerable |> Enum.to_list() |> :maps.from_list() 1450 1451 defp into_map(%{} = enumerable, collectable), 1452 do: Map.merge(collectable, enumerable) 1453 1454 defp into_map(enumerable, collectable) when is_list(enumerable), 1455 do: Map.merge(collectable, :maps.from_list(enumerable)) 1456 1457 defp into_map(enumerable, collectable), 1458 do: Enum.reduce(enumerable, collectable, fn {key, val}, acc -> Map.put(acc, key, val) end) 1459 1460 defp into_protocol(enumerable, collectable) do 1461 {initial, fun} = Collectable.into(collectable) 1462 1463 into_protocol(enumerable, initial, fun, fn entry, acc -> 1464 fun.(acc, {:cont, entry}) 1465 end) 1466 end 1467 1468 @doc """ 1469 Inserts the given `enumerable` into a `collectable` according to the 1470 transformation function. 1471 1472 ## Examples 1473 1474 iex> Enum.into([1, 2, 3], [], fn x -> x * 3 end) 1475 [3, 6, 9] 1476 1477 iex> Enum.into(%{a: 1, b: 2}, %{c: 3}, fn {k, v} -> {k, v * 2} end) 1478 %{a: 2, b: 4, c: 3} 1479 1480 """ 1481 @spec into(Enumerable.t(), Collectable.t(), (term -> term)) :: Collectable.t() 1482 def into(enumerable, [], transform) do 1483 Enum.map(enumerable, transform) 1484 end 1485 1486 def into(%_{} = enumerable, collectable, transform) do 1487 into_protocol(enumerable, collectable, transform) 1488 end 1489 1490 def into(enumerable, %_{} = collectable, transform) do 1491 into_protocol(enumerable, collectable, transform) 1492 end 1493 1494 def into(enumerable, %{} = collectable, transform) do 1495 if map_size(collectable) == 0 do 1496 enumerable |> Enum.map(transform) |> :maps.from_list() 1497 else 1498 Enum.reduce(enumerable, collectable, fn entry, acc -> 1499 {key, val} = transform.(entry) 1500 Map.put(acc, key, val) 1501 end) 1502 end 1503 end 1504 1505 def into(enumerable, collectable, transform) do 1506 into_protocol(enumerable, collectable, transform) 1507 end 1508 1509 defp into_protocol(enumerable, collectable, transform) do 1510 {initial, fun} = Collectable.into(collectable) 1511 1512 into_protocol(enumerable, initial, fun, fn entry, acc -> 1513 fun.(acc, {:cont, transform.(entry)}) 1514 end) 1515 end 1516 1517 defp into_protocol(enumerable, initial, fun, callback) do 1518 try do 1519 reduce(enumerable, initial, callback) 1520 catch 1521 kind, reason -> 1522 fun.(initial, :halt) 1523 :erlang.raise(kind, reason, __STACKTRACE__) 1524 else 1525 acc -> fun.(acc, :done) 1526 end 1527 end 1528 1529 @doc """ 1530 Joins the given `enumerable` into a string using `joiner` as a 1531 separator. 1532 1533 If `joiner` is not passed at all, it defaults to an empty string. 1534 1535 All elements in the `enumerable` must be convertible to a string, 1536 otherwise an error is raised. 1537 1538 ## Examples 1539 1540 iex> Enum.join([1, 2, 3]) 1541 "123" 1542 1543 iex> Enum.join([1, 2, 3], " = ") 1544 "1 = 2 = 3" 1545 1546 """ 1547 @spec join(t, String.t()) :: String.t() 1548 def join(enumerable, joiner \\ "") 1549 1550 def join(enumerable, "") do 1551 enumerable 1552 |> map(&entry_to_string(&1)) 1553 |> IO.iodata_to_binary() 1554 end 1555 1556 def join(enumerable, joiner) when is_list(enumerable) and is_binary(joiner) do 1557 join_list(enumerable, joiner) 1558 end 1559 1560 def join(enumerable, joiner) when is_binary(joiner) do 1561 reduced = 1562 reduce(enumerable, :first, fn 1563 entry, :first -> entry_to_string(entry) 1564 entry, acc -> [acc, joiner | entry_to_string(entry)] 1565 end) 1566 1567 if reduced == :first do 1568 "" 1569 else 1570 IO.iodata_to_binary(reduced) 1571 end 1572 end 1573 1574 @doc """ 1575 Returns a list where each element is the result of invoking 1576 `fun` on each corresponding element of `enumerable`. 1577 1578 For maps, the function expects a key-value tuple. 1579 1580 ## Examples 1581 1582 iex> Enum.map([1, 2, 3], fn x -> x * 2 end) 1583 [2, 4, 6] 1584 1585 iex> Enum.map([a: 1, b: 2], fn {k, v} -> {k, -v} end) 1586 [a: -1, b: -2] 1587 1588 """ 1589 @spec map(t, (element -> any)) :: list 1590 def map(enumerable, fun) 1591 1592 def map(enumerable, fun) when is_list(enumerable) do 1593 :lists.map(fun, enumerable) 1594 end 1595 1596 def map(enumerable, fun) do 1597 reduce(enumerable, [], R.map(fun)) |> :lists.reverse() 1598 end 1599 1600 @doc """ 1601 Returns a list of results of invoking `fun` on every `nth` 1602 element of `enumerable`, starting with the first element. 1603 1604 The first element is always passed to the given function, unless `nth` is `0`. 1605 1606 The second argument specifying every `nth` element must be a non-negative 1607 integer. 1608 1609 If `nth` is `0`, then `enumerable` is directly converted to a list, 1610 without `fun` being ever applied. 1611 1612 ## Examples 1613 1614 iex> Enum.map_every(1..10, 2, fn x -> x + 1000 end) 1615 [1001, 2, 1003, 4, 1005, 6, 1007, 8, 1009, 10] 1616 1617 iex> Enum.map_every(1..10, 3, fn x -> x + 1000 end) 1618 [1001, 2, 3, 1004, 5, 6, 1007, 8, 9, 1010] 1619 1620 iex> Enum.map_every(1..5, 0, fn x -> x + 1000 end) 1621 [1, 2, 3, 4, 5] 1622 1623 iex> Enum.map_every([1, 2, 3], 1, fn x -> x + 1000 end) 1624 [1001, 1002, 1003] 1625 1626 """ 1627 @doc since: "1.4.0" 1628 @spec map_every(t, non_neg_integer, (element -> any)) :: list 1629 def map_every(enumerable, nth, fun) 1630 1631 def map_every(enumerable, 1, fun), do: map(enumerable, fun) 1632 def map_every(enumerable, 0, _fun), do: to_list(enumerable) 1633 def map_every([], nth, _fun) when is_integer(nth) and nth > 1, do: [] 1634 1635 def map_every(enumerable, nth, fun) when is_integer(nth) and nth > 1 do 1636 {res, _} = reduce(enumerable, {[], :first}, R.map_every(nth, fun)) 1637 :lists.reverse(res) 1638 end 1639 1640 @doc """ 1641 Maps and intersperses the given enumerable in one pass. 1642 1643 ## Examples 1644 1645 iex> Enum.map_intersperse([1, 2, 3], :a, &(&1 * 2)) 1646 [2, :a, 4, :a, 6] 1647 """ 1648 @doc since: "1.10.0" 1649 @spec map_intersperse(t, element(), (element -> any())) :: list() 1650 def map_intersperse(enumerable, separator, mapper) 1651 1652 def map_intersperse(enumerable, separator, mapper) when is_list(enumerable) do 1653 map_intersperse_list(enumerable, separator, mapper) 1654 end 1655 1656 def map_intersperse(enumerable, separator, mapper) do 1657 reduced = 1658 reduce(enumerable, :first, fn 1659 entry, :first -> [mapper.(entry)] 1660 entry, acc -> [mapper.(entry), separator | acc] 1661 end) 1662 1663 if reduced == :first do 1664 [] 1665 else 1666 :lists.reverse(reduced) 1667 end 1668 end 1669 1670 @doc """ 1671 Maps and joins the given `enumerable` in one pass. 1672 1673 If `joiner` is not passed at all, it defaults to an empty string. 1674 1675 All elements returned from invoking the `mapper` must be convertible to 1676 a string, otherwise an error is raised. 1677 1678 ## Examples 1679 1680 iex> Enum.map_join([1, 2, 3], &(&1 * 2)) 1681 "246" 1682 1683 iex> Enum.map_join([1, 2, 3], " = ", &(&1 * 2)) 1684 "2 = 4 = 6" 1685 1686 """ 1687 @spec map_join(t, String.t(), (element -> String.Chars.t())) :: String.t() 1688 def map_join(enumerable, joiner \\ "", mapper) when is_binary(joiner) do 1689 enumerable 1690 |> map_intersperse(joiner, &entry_to_string(mapper.(&1))) 1691 |> IO.iodata_to_binary() 1692 end 1693 1694 @doc """ 1695 Invokes the given function to each element in the `enumerable` to reduce 1696 it to a single element, while keeping an accumulator. 1697 1698 Returns a tuple where the first element is the mapped enumerable and 1699 the second one is the final accumulator. 1700 1701 The function, `fun`, receives two arguments: the first one is the 1702 element, and the second one is the accumulator. `fun` must return 1703 a tuple with two elements in the form of `{result, accumulator}`. 1704 1705 For maps, the first tuple element must be a `{key, value}` tuple. 1706 1707 ## Examples 1708 1709 iex> Enum.map_reduce([1, 2, 3], 0, fn x, acc -> {x * 2, x + acc} end) 1710 {[2, 4, 6], 6} 1711 1712 """ 1713 @spec map_reduce(t, acc, (element, acc -> {element, acc})) :: {list, acc} 1714 def map_reduce(enumerable, acc, fun) when is_list(enumerable) do 1715 :lists.mapfoldl(fun, acc, enumerable) 1716 end 1717 1718 def map_reduce(enumerable, acc, fun) do 1719 {list, acc} = 1720 reduce(enumerable, {[], acc}, fn entry, {list, acc} -> 1721 {new_entry, acc} = fun.(entry, acc) 1722 {[new_entry | list], acc} 1723 end) 1724 1725 {:lists.reverse(list), acc} 1726 end 1727 1728 @doc false 1729 def max(list = [_ | _]), do: :lists.max(list) 1730 1731 @doc false 1732 def max(list = [_ | _], empty_fallback) when is_function(empty_fallback, 0) do 1733 :lists.max(list) 1734 end 1735 1736 @doc false 1737 @spec max(t, (() -> empty_result)) :: element | empty_result when empty_result: any 1738 def max(enumerable, empty_fallback) when is_function(empty_fallback, 0) do 1739 max(enumerable, &>=/2, empty_fallback) 1740 end 1741 1742 @doc """ 1743 Returns the maximal element in the `enumerable` according 1744 to Erlang's term ordering. 1745 1746 By default, the comparison is done with the `>=` sorter function. 1747 If multiple elements are considered maximal, the first one that 1748 was found is returned. If you want the last element considered 1749 maximal to be returned, the sorter function should not return true 1750 for equal elements. 1751 1752 If the enumerable is empty, the provided `empty_fallback` is called. 1753 The default `empty_fallback` raises `Enum.EmptyError`. 1754 1755 ## Examples 1756 1757 iex> Enum.max([1, 2, 3]) 1758 3 1759 1760 The fact this function uses Erlang's term ordering means that the comparison 1761 is structural and not semantic. For example: 1762 1763 iex> Enum.max([~D[2017-03-31], ~D[2017-04-01]]) 1764 ~D[2017-03-31] 1765 1766 In the example above, `max/2` returned March 31st instead of April 1st 1767 because the structural comparison compares the day before the year. 1768 For this reason, most structs provide a "compare" function, such as 1769 `Date.compare/2`, which receives two structs and returns `:lt` (less-than), 1770 `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the 1771 sorting function, Elixir will automatically use the `compare/2` function 1772 of said module: 1773 1774 iex> Enum.max([~D[2017-03-31], ~D[2017-04-01]], Date) 1775 ~D[2017-04-01] 1776 1777 Finally, if you don't want to raise on empty enumerables, you can pass 1778 the empty fallback: 1779 1780 iex> Enum.max([], &>=/2, fn -> 0 end) 1781 0 1782 1783 """ 1784 @spec max(t, (element, element -> boolean) | module()) :: 1785 element | empty_result 1786 when empty_result: any 1787 @spec max(t, (element, element -> boolean) | module(), (() -> empty_result)) :: 1788 element | empty_result 1789 when empty_result: any 1790 def max(enumerable, sorter \\ &>=/2, empty_fallback \\ fn -> raise Enum.EmptyError end) do 1791 aggregate(enumerable, max_sort_fun(sorter), empty_fallback) 1792 end 1793 1794 defp max_sort_fun(sorter) when is_function(sorter, 2), do: sorter 1795 defp max_sort_fun(module) when is_atom(module), do: &(module.compare(&1, &2) != :lt) 1796 1797 @doc false 1798 @spec max_by( 1799 t, 1800 (element -> any), 1801 (() -> empty_result) | (element, element -> boolean) | module() 1802 ) :: element | empty_result 1803 when empty_result: any 1804 def max_by(enumerable, fun, empty_fallback) 1805 when is_function(fun, 1) and is_function(empty_fallback, 0) do 1806 max_by(enumerable, fun, &>=/2, empty_fallback) 1807 end 1808 1809 @doc """ 1810 Returns the maximal element in the `enumerable` as calculated 1811 by the given `fun`. 1812 1813 By default, the comparison is done with the `>=` sorter function. 1814 If multiple elements are considered maximal, the first one that 1815 was found is returned. If you want the last element considered 1816 maximal to be returned, the sorter function should not return true 1817 for equal elements. 1818 1819 Calls the provided `empty_fallback` function and returns its value if 1820 `enumerable` is empty. The default `empty_fallback` raises `Enum.EmptyError`. 1821 1822 ## Examples 1823 1824 iex> Enum.max_by(["a", "aa", "aaa"], fn x -> String.length(x) end) 1825 "aaa" 1826 1827 iex> Enum.max_by(["a", "aa", "aaa", "b", "bbb"], &String.length/1) 1828 "aaa" 1829 1830 The fact this function uses Erlang's term ordering means that the 1831 comparison is structural and not semantic. Therefore, if you want 1832 to compare structs, most structs provide a "compare" function, such as 1833 `Date.compare/2`, which receives two structs and returns `:lt` (less-than), 1834 `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the 1835 sorting function, Elixir will automatically use the `compare/2` function 1836 of said module: 1837 1838 iex> users = [ 1839 ...> %{name: "Ellis", birthday: ~D[1943-05-11]}, 1840 ...> %{name: "Lovelace", birthday: ~D[1815-12-10]}, 1841 ...> %{name: "Turing", birthday: ~D[1912-06-23]} 1842 ...> ] 1843 iex> Enum.max_by(users, &(&1.birthday), Date) 1844 %{name: "Ellis", birthday: ~D[1943-05-11]} 1845 1846 Finally, if you don't want to raise on empty enumerables, you can pass 1847 the empty fallback: 1848 1849 iex> Enum.max_by([], &String.length/1, fn -> nil end) 1850 nil 1851 1852 """ 1853 @spec max_by( 1854 t, 1855 (element -> any), 1856 (element, element -> boolean) | module(), 1857 (() -> empty_result) 1858 ) :: element | empty_result 1859 when empty_result: any 1860 def max_by(enumerable, fun, sorter \\ &>=/2, empty_fallback \\ fn -> raise Enum.EmptyError end) 1861 when is_function(fun, 1) do 1862 aggregate_by(enumerable, fun, max_sort_fun(sorter), empty_fallback) 1863 end 1864 1865 @doc """ 1866 Checks if `element` exists within the `enumerable`. 1867 1868 Membership is tested with the match (`===/2`) operator. 1869 1870 ## Examples 1871 1872 iex> Enum.member?(1..10, 5) 1873 true 1874 iex> Enum.member?(1..10, 5.0) 1875 false 1876 1877 iex> Enum.member?([1.0, 2.0, 3.0], 2) 1878 false 1879 iex> Enum.member?([1.0, 2.0, 3.0], 2.000) 1880 true 1881 1882 iex> Enum.member?([:a, :b, :c], :d) 1883 false 1884 1885 1886 When called outside guards, the [`in`](`in/2`) and [`not in`](`in/2`) 1887 operators work by using this function. 1888 """ 1889 @spec member?(t, element) :: boolean 1890 def member?(enumerable, element) when is_list(enumerable) do 1891 :lists.member(element, enumerable) 1892 end 1893 1894 def member?(enumerable, element) do 1895 case Enumerable.member?(enumerable, element) do 1896 {:ok, element} when is_boolean(element) -> 1897 element 1898 1899 {:error, module} -> 1900 module.reduce(enumerable, {:cont, false}, fn 1901 v, _ when v === element -> {:halt, true} 1902 _, _ -> {:cont, false} 1903 end) 1904 |> elem(1) 1905 end 1906 end 1907 1908 @doc false 1909 def min(list = [_ | _]), do: :lists.min(list) 1910 1911 @doc false 1912 def min(list = [_ | _], empty_fallback) when is_function(empty_fallback, 0) do 1913 :lists.min(list) 1914 end 1915 1916 @doc false 1917 @spec min(t, (() -> empty_result)) :: element | empty_result when empty_result: any 1918 def min(enumerable, empty_fallback) when is_function(empty_fallback, 0) do 1919 min(enumerable, &<=/2, empty_fallback) 1920 end 1921 1922 @doc """ 1923 Returns the minimal element in the `enumerable` according 1924 to Erlang's term ordering. 1925 1926 By default, the comparison is done with the `<=` sorter function. 1927 If multiple elements are considered minimal, the first one that 1928 was found is returned. If you want the last element considered 1929 minimal to be returned, the sorter function should not return true 1930 for equal elements. 1931 1932 If the enumerable is empty, the provided `empty_fallback` is called. 1933 The default `empty_fallback` raises `Enum.EmptyError`. 1934 1935 ## Examples 1936 1937 iex> Enum.min([1, 2, 3]) 1938 1 1939 1940 The fact this function uses Erlang's term ordering means that the comparison 1941 is structural and not semantic. For example: 1942 1943 iex> Enum.min([~D[2017-03-31], ~D[2017-04-01]]) 1944 ~D[2017-04-01] 1945 1946 In the example above, `min/2` returned April 1st instead of March 31st 1947 because the structural comparison compares the day before the year. 1948 For this reason, most structs provide a "compare" function, such as 1949 `Date.compare/2`, which receives two structs and returns `:lt` (less-than), 1950 `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the 1951 sorting function, Elixir will automatically use the `compare/2` function 1952 of said module: 1953 1954 iex> Enum.min([~D[2017-03-31], ~D[2017-04-01]], Date) 1955 ~D[2017-03-31] 1956 1957 Finally, if you don't want to raise on empty enumerables, you can pass 1958 the empty fallback: 1959 1960 iex> Enum.min([], fn -> 0 end) 1961 0 1962 1963 """ 1964 @spec min(t, (element, element -> boolean) | module()) :: 1965 element | empty_result 1966 when empty_result: any 1967 @spec min(t, (element, element -> boolean) | module(), (() -> empty_result)) :: 1968 element | empty_result 1969 when empty_result: any 1970 def min(enumerable, sorter \\ &<=/2, empty_fallback \\ fn -> raise Enum.EmptyError end) do 1971 aggregate(enumerable, min_sort_fun(sorter), empty_fallback) 1972 end 1973 1974 defp min_sort_fun(sorter) when is_function(sorter, 2), do: sorter 1975 defp min_sort_fun(module) when is_atom(module), do: &(module.compare(&1, &2) != :gt) 1976 1977 @doc false 1978 @spec min_by( 1979 t, 1980 (element -> any), 1981 (() -> empty_result) | (element, element -> boolean) | module() 1982 ) :: element | empty_result 1983 when empty_result: any 1984 def min_by(enumerable, fun, empty_fallback) 1985 when is_function(fun, 1) and is_function(empty_fallback, 0) do 1986 min_by(enumerable, fun, &<=/2, empty_fallback) 1987 end 1988 1989 @doc """ 1990 Returns the minimal element in the `enumerable` as calculated 1991 by the given `fun`. 1992 1993 By default, the comparison is done with the `<=` sorter function. 1994 If multiple elements are considered minimal, the first one that 1995 was found is returned. If you want the last element considered 1996 minimal to be returned, the sorter function should not return true 1997 for equal elements. 1998 1999 Calls the provided `empty_fallback` function and returns its value if 2000 `enumerable` is empty. The default `empty_fallback` raises `Enum.EmptyError`. 2001 2002 ## Examples 2003 2004 iex> Enum.min_by(["a", "aa", "aaa"], fn x -> String.length(x) end) 2005 "a" 2006 2007 iex> Enum.min_by(["a", "aa", "aaa", "b", "bbb"], &String.length/1) 2008 "a" 2009 2010 The fact this function uses Erlang's term ordering means that the 2011 comparison is structural and not semantic. Therefore, if you want 2012 to compare structs, most structs provide a "compare" function, such as 2013 `Date.compare/2`, which receives two structs and returns `:lt` (less-than), 2014 `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the 2015 sorting function, Elixir will automatically use the `compare/2` function 2016 of said module: 2017 2018 iex> users = [ 2019 ...> %{name: "Ellis", birthday: ~D[1943-05-11]}, 2020 ...> %{name: "Lovelace", birthday: ~D[1815-12-10]}, 2021 ...> %{name: "Turing", birthday: ~D[1912-06-23]} 2022 ...> ] 2023 iex> Enum.min_by(users, &(&1.birthday), Date) 2024 %{name: "Lovelace", birthday: ~D[1815-12-10]} 2025 2026 Finally, if you don't want to raise on empty enumerables, you can pass 2027 the empty fallback: 2028 2029 iex> Enum.min_by([], &String.length/1, fn -> nil end) 2030 nil 2031 2032 """ 2033 @spec min_by( 2034 t, 2035 (element -> any), 2036 (element, element -> boolean) | module(), 2037 (() -> empty_result) 2038 ) :: element | empty_result 2039 when empty_result: any 2040 def min_by(enumerable, fun, sorter \\ &<=/2, empty_fallback \\ fn -> raise Enum.EmptyError end) 2041 when is_function(fun, 1) do 2042 aggregate_by(enumerable, fun, min_sort_fun(sorter), empty_fallback) 2043 end 2044 2045 @doc """ 2046 Returns a tuple with the minimal and the maximal elements in the 2047 enumerable according to Erlang's term ordering. 2048 2049 If multiple elements are considered maximal or minimal, the first one 2050 that was found is returned. 2051 2052 Calls the provided `empty_fallback` function and returns its value if 2053 `enumerable` is empty. The default `empty_fallback` raises `Enum.EmptyError`. 2054 2055 ## Examples 2056 2057 iex> Enum.min_max([2, 3, 1]) 2058 {1, 3} 2059 2060 iex> Enum.min_max([], fn -> {nil, nil} end) 2061 {nil, nil} 2062 2063 """ 2064 @spec min_max(t, (() -> empty_result)) :: {element, element} | empty_result 2065 when empty_result: any 2066 def min_max(enumerable, empty_fallback \\ fn -> raise Enum.EmptyError end) 2067 2068 def min_max(first..last//step = range, empty_fallback) when is_function(empty_fallback, 0) do 2069 case Range.size(range) do 2070 0 -> 2071 empty_fallback.() 2072 2073 _ -> 2074 last = last - rem(last - first, step) 2075 {Kernel.min(first, last), Kernel.max(first, last)} 2076 end 2077 end 2078 2079 def min_max(enumerable, empty_fallback) when is_function(empty_fallback, 0) do 2080 first_fun = &[&1 | &1] 2081 2082 reduce_fun = fn entry, [min | max] -> 2083 [Kernel.min(min, entry) | Kernel.max(max, entry)] 2084 end 2085 2086 case reduce_by(enumerable, first_fun, reduce_fun) do 2087 :empty -> empty_fallback.() 2088 [min | max] -> {min, max} 2089 end 2090 end 2091 2092 @doc false 2093 @spec min_max_by(t, (element -> any), (() -> empty_result)) :: {element, element} | empty_result 2094 when empty_result: any 2095 def min_max_by(enumerable, fun, empty_fallback) 2096 when is_function(fun, 1) and is_function(empty_fallback, 0) do 2097 min_max_by(enumerable, fun, &</2, empty_fallback) 2098 end 2099 2100 @doc """ 2101 Returns a tuple with the minimal and the maximal elements in the 2102 enumerable as calculated by the given function. 2103 2104 If multiple elements are considered maximal or minimal, the first one 2105 that was found is returned. 2106 2107 ## Examples 2108 2109 iex> Enum.min_max_by(["aaa", "bb", "c"], fn x -> String.length(x) end) 2110 {"c", "aaa"} 2111 2112 iex> Enum.min_max_by(["aaa", "a", "bb", "c", "ccc"], &String.length/1) 2113 {"a", "aaa"} 2114 2115 iex> Enum.min_max_by([], &String.length/1, fn -> {nil, nil} end) 2116 {nil, nil} 2117 2118 The fact this function uses Erlang's term ordering means that the 2119 comparison is structural and not semantic. Therefore, if you want 2120 to compare structs, most structs provide a "compare" function, such as 2121 `Date.compare/2`, which receives two structs and returns `:lt` (less-than), 2122 `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the 2123 sorting function, Elixir will automatically use the `compare/2` function 2124 of said module: 2125 2126 iex> users = [ 2127 ...> %{name: "Ellis", birthday: ~D[1943-05-11]}, 2128 ...> %{name: "Lovelace", birthday: ~D[1815-12-10]}, 2129 ...> %{name: "Turing", birthday: ~D[1912-06-23]} 2130 ...> ] 2131 iex> Enum.min_max_by(users, &(&1.birthday), Date) 2132 { 2133 %{name: "Lovelace", birthday: ~D[1815-12-10]}, 2134 %{name: "Ellis", birthday: ~D[1943-05-11]} 2135 } 2136 2137 Finally, if you don't want to raise on empty enumerables, you can pass 2138 the empty fallback: 2139 2140 iex> Enum.min_max_by([], &String.length/1, fn -> nil end) 2141 nil 2142 2143 """ 2144 @spec min_max_by(t, (element -> any), (element, element -> boolean) | module()) :: 2145 {element, element} | empty_result 2146 when empty_result: any 2147 @spec min_max_by( 2148 t, 2149 (element -> any), 2150 (element, element -> boolean) | module(), 2151 (() -> empty_result) 2152 ) :: {element, element} | empty_result 2153 when empty_result: any 2154 def min_max_by( 2155 enumerable, 2156 fun, 2157 sorter_or_empty_fallback \\ &</2, 2158 empty_fallback \\ fn -> raise Enum.EmptyError end 2159 ) 2160 2161 def min_max_by(enumerable, fun, sorter, empty_fallback) 2162 when is_function(fun, 1) and is_atom(sorter) and is_function(empty_fallback, 0) do 2163 min_max_by(enumerable, fun, min_max_by_sort_fun(sorter), empty_fallback) 2164 end 2165 2166 def min_max_by(enumerable, fun, sorter, empty_fallback) 2167 when is_function(fun, 1) and is_function(sorter, 2) and is_function(empty_fallback, 0) do 2168 first_fun = fn entry -> 2169 fun_entry = fun.(entry) 2170 {entry, entry, fun_entry, fun_entry} 2171 end 2172 2173 reduce_fun = fn entry, {prev_min, prev_max, fun_min, fun_max} = acc -> 2174 fun_entry = fun.(entry) 2175 2176 cond do 2177 sorter.(fun_entry, fun_min) -> 2178 {entry, prev_max, fun_entry, fun_max} 2179 2180 sorter.(fun_max, fun_entry) -> 2181 {prev_min, entry, fun_min, fun_entry} 2182 2183 true -> 2184 acc 2185 end 2186 end 2187 2188 case reduce_by(enumerable, first_fun, reduce_fun) do 2189 :empty -> empty_fallback.() 2190 {min, max, _, _} -> {min, max} 2191 end 2192 end 2193 2194 defp min_max_by_sort_fun(module) when is_atom(module), do: &(module.compare(&1, &2) == :lt) 2195 2196 @doc """ 2197 Splits the `enumerable` in two lists according to the given function `fun`. 2198 2199 Splits the given `enumerable` in two lists by calling `fun` with each element 2200 in the `enumerable` as its only argument. Returns a tuple with the first list 2201 containing all the elements in `enumerable` for which applying `fun` returned 2202 a truthy value, and a second list with all the elements for which applying 2203 `fun` returned a falsy value (`false` or `nil`). 2204 2205 The elements in both the returned lists are in the same relative order as they 2206 were in the original enumerable (if such enumerable was ordered, like a 2207 list). See the examples below. 2208 2209 ## Examples 2210 2211 iex> Enum.split_with([5, 4, 3, 2, 1, 0], fn x -> rem(x, 2) == 0 end) 2212 {[4, 2, 0], [5, 3, 1]} 2213 2214 iex> Enum.split_with(%{a: 1, b: -2, c: 1, d: -3}, fn {_k, v} -> v < 0 end) 2215 {[b: -2, d: -3], [a: 1, c: 1]} 2216 2217 iex> Enum.split_with(%{a: 1, b: -2, c: 1, d: -3}, fn {_k, v} -> v > 50 end) 2218 {[], [a: 1, b: -2, c: 1, d: -3]} 2219 2220 iex> Enum.split_with(%{}, fn {_k, v} -> v > 50 end) 2221 {[], []} 2222 2223 """ 2224 @doc since: "1.4.0" 2225 @spec split_with(t, (element -> as_boolean(term))) :: {list, list} 2226 def split_with(enumerable, fun) do 2227 {acc1, acc2} = 2228 reduce(enumerable, {[], []}, fn entry, {acc1, acc2} -> 2229 if fun.(entry) do 2230 {[entry | acc1], acc2} 2231 else 2232 {acc1, [entry | acc2]} 2233 end 2234 end) 2235 2236 {:lists.reverse(acc1), :lists.reverse(acc2)} 2237 end 2238 2239 @doc false 2240 @deprecated "Use Enum.split_with/2 instead" 2241 def partition(enumerable, fun) do 2242 split_with(enumerable, fun) 2243 end 2244 2245 @doc """ 2246 Returns a random element of an `enumerable`. 2247 2248 Raises `Enum.EmptyError` if `enumerable` is empty. 2249 2250 This function uses Erlang's [`:rand` module](`:rand`) to calculate 2251 the random value. Check its documentation for setting a 2252 different random algorithm or a different seed. 2253 2254 The implementation is based on the 2255 [reservoir sampling](https://en.wikipedia.org/wiki/Reservoir_sampling#Relation_to_Fisher-Yates_shuffle) 2256 algorithm. 2257 It assumes that the sample being returned can fit into memory; 2258 the input `enumerable` doesn't have to, as it is traversed just once. 2259 2260 If a range is passed into the function, this function will pick a 2261 random value between the range limits, without traversing the whole 2262 range (thus executing in constant time and constant memory). 2263 2264 ## Examples 2265 2266 The examples below use the `:exsss` pseudorandom algorithm since it's 2267 the default from Erlang/OTP 22: 2268 2269 # Although not necessary, let's seed the random algorithm 2270 iex> :rand.seed(:exsss, {100, 101, 102}) 2271 iex> Enum.random([1, 2, 3]) 2272 2 2273 iex> Enum.random([1, 2, 3]) 2274 1 2275 iex> Enum.random(1..1_000) 2276 309 2277 2278 """ 2279 @spec random(t) :: element 2280 def random(enumerable) 2281 2282 def random(enumerable) when is_list(enumerable) do 2283 case length(enumerable) do 2284 0 -> raise Enum.EmptyError 2285 length -> enumerable |> drop_list(random_integer(0, length - 1)) |> hd() 2286 end 2287 end 2288 2289 def random(enumerable) do 2290 result = 2291 case Enumerable.slice(enumerable) do 2292 {:ok, 0, _} -> 2293 [] 2294 2295 {:ok, count, fun} when is_function(fun) -> 2296 fun.(random_integer(0, count - 1), 1) 2297 2298 {:error, _} -> 2299 take_random(enumerable, 1) 2300 end 2301 2302 case result do 2303 [] -> raise Enum.EmptyError 2304 [elem] -> elem 2305 end 2306 end 2307 2308 @doc """ 2309 Invokes `fun` for each element in the `enumerable` with the 2310 accumulator. 2311 2312 Raises `Enum.EmptyError` if `enumerable` is empty. 2313 2314 The first element of the `enumerable` is used as the initial value 2315 of the accumulator. Then, the function is invoked with the next 2316 element and the accumulator. The result returned by the function 2317 is used as the accumulator for the next iteration, recursively. 2318 When the `enumerable` is done, the last accumulator is returned. 2319 2320 Since the first element of the enumerable is used as the initial 2321 value of the accumulator, `fun` will only be executed `n - 1` times 2322 where `n` is the length of the enumerable. This function won't call 2323 the specified function for enumerables that are one-element long. 2324 2325 If you wish to use another value for the accumulator, use 2326 `Enum.reduce/3`. 2327 2328 ## Examples 2329 2330 iex> Enum.reduce([1, 2, 3, 4], fn x, acc -> x * acc end) 2331 24 2332 2333 """ 2334 @spec reduce(t, (element, acc -> acc)) :: acc 2335 def reduce(enumerable, fun) 2336 2337 def reduce([h | t], fun) do 2338 reduce(t, h, fun) 2339 end 2340 2341 def reduce([], _fun) do 2342 raise Enum.EmptyError 2343 end 2344 2345 def reduce(enumerable, fun) do 2346 Enumerable.reduce(enumerable, {:cont, :first}, fn 2347 x, {:acc, acc} -> {:cont, {:acc, fun.(x, acc)}} 2348 x, :first -> {:cont, {:acc, x}} 2349 end) 2350 |> elem(1) 2351 |> case do 2352 :first -> raise Enum.EmptyError 2353 {:acc, acc} -> acc 2354 end 2355 end 2356 2357 @doc """ 2358 Invokes `fun` for each element in the `enumerable` with the accumulator. 2359 2360 The initial value of the accumulator is `acc`. The function is invoked for 2361 each element in the enumerable with the accumulator. The result returned 2362 by the function is used as the accumulator for the next iteration. 2363 The function returns the last accumulator. 2364 2365 ## Examples 2366 2367 iex> Enum.reduce([1, 2, 3], 0, fn x, acc -> x + acc end) 2368 6 2369 2370 ## Reduce as a building block 2371 2372 Reduce (sometimes called `fold`) is a basic building block in functional 2373 programming. Almost all of the functions in the `Enum` module can be 2374 implemented on top of reduce. Those functions often rely on other operations, 2375 such as `Enum.reverse/1`, which are optimized by the runtime. 2376 2377 For example, we could implement `map/2` in terms of `reduce/3` as follows: 2378 2379 def my_map(enumerable, fun) do 2380 enumerable 2381 |> Enum.reduce([], fn x, acc -> [fun.(x) | acc] end) 2382 |> Enum.reverse() 2383 end 2384 2385 In the example above, `Enum.reduce/3` accumulates the result of each call 2386 to `fun` into a list in reverse order, which is correctly ordered at the 2387 end by calling `Enum.reverse/1`. 2388 2389 Implementing functions like `map/2`, `filter/2` and others are a good 2390 exercise for understanding the power behind `Enum.reduce/3`. When an 2391 operation cannot be expressed by any of the functions in the `Enum` 2392 module, developers will most likely resort to `reduce/3`. 2393 """ 2394 @spec reduce(t, acc, (element, acc -> acc)) :: acc 2395 def reduce(enumerable, acc, fun) when is_list(enumerable) do 2396 :lists.foldl(fun, acc, enumerable) 2397 end 2398 2399 def reduce(first..last//step, acc, fun) do 2400 reduce_range(first, last, step, acc, fun) 2401 end 2402 2403 def reduce(%_{} = enumerable, acc, fun) do 2404 reduce_enumerable(enumerable, acc, fun) 2405 end 2406 2407 def reduce(%{} = enumerable, acc, fun) do 2408 :maps.fold(fn k, v, acc -> fun.({k, v}, acc) end, acc, enumerable) 2409 end 2410 2411 def reduce(enumerable, acc, fun) do 2412 reduce_enumerable(enumerable, acc, fun) 2413 end 2414 2415 @doc """ 2416 Reduces `enumerable` until `fun` returns `{:halt, term}`. 2417 2418 The return value for `fun` is expected to be 2419 2420 * `{:cont, acc}` to continue the reduction with `acc` as the new 2421 accumulator or 2422 * `{:halt, acc}` to halt the reduction 2423 2424 If `fun` returns `{:halt, acc}` the reduction is halted and the function 2425 returns `acc`. Otherwise, if the enumerable is exhausted, the function returns 2426 the accumulator of the last `{:cont, acc}`. 2427 2428 ## Examples 2429 2430 iex> Enum.reduce_while(1..100, 0, fn x, acc -> 2431 ...> if x < 5, do: {:cont, acc + x}, else: {:halt, acc} 2432 ...> end) 2433 10 2434 iex> Enum.reduce_while(1..100, 0, fn x, acc -> 2435 ...> if x > 0, do: {:cont, acc + x}, else: {:halt, acc} 2436 ...> end) 2437 5050 2438 2439 """ 2440 @spec reduce_while(t, any, (element, any -> {:cont, any} | {:halt, any})) :: any 2441 def reduce_while(enumerable, acc, fun) do 2442 Enumerable.reduce(enumerable, {:cont, acc}, fun) |> elem(1) 2443 end 2444 2445 @doc """ 2446 Returns a list of elements in `enumerable` excluding those for which the function `fun` returns 2447 a truthy value. 2448 2449 See also `filter/2`. 2450 2451 ## Examples 2452 2453 iex> Enum.reject([1, 2, 3], fn x -> rem(x, 2) == 0 end) 2454 [1, 3] 2455 2456 """ 2457 @spec reject(t, (element -> as_boolean(term))) :: list 2458 def reject(enumerable, fun) when is_list(enumerable) do 2459 reject_list(enumerable, fun) 2460 end 2461 2462 def reject(enumerable, fun) do 2463 reduce(enumerable, [], R.reject(fun)) |> :lists.reverse() 2464 end 2465 2466 @doc """ 2467 Returns a list of elements in `enumerable` in reverse order. 2468 2469 ## Examples 2470 2471 iex> Enum.reverse([1, 2, 3]) 2472 [3, 2, 1] 2473 2474 """ 2475 @spec reverse(t) :: list 2476 def reverse(enumerable) 2477 2478 def reverse([]), do: [] 2479 def reverse([_] = list), do: list 2480 def reverse([element1, element2]), do: [element2, element1] 2481 def reverse([element1, element2 | rest]), do: :lists.reverse(rest, [element2, element1]) 2482 def reverse(enumerable), do: reduce(enumerable, [], &[&1 | &2]) 2483 2484 @doc """ 2485 Reverses the elements in `enumerable`, appends the `tail`, and returns 2486 it as a list. 2487 2488 This is an optimization for 2489 `enumerable |> Enum.reverse() |> Enum.concat(tail)`. 2490 2491 ## Examples 2492 2493 iex> Enum.reverse([1, 2, 3], [4, 5, 6]) 2494 [3, 2, 1, 4, 5, 6] 2495 2496 """ 2497 @spec reverse(t, t) :: list 2498 def reverse(enumerable, tail) when is_list(enumerable) do 2499 :lists.reverse(enumerable, to_list(tail)) 2500 end 2501 2502 def reverse(enumerable, tail) do 2503 reduce(enumerable, to_list(tail), fn entry, acc -> 2504 [entry | acc] 2505 end) 2506 end 2507 2508 @doc """ 2509 Reverses the `enumerable` in the range from initial `start_index` 2510 through `count` elements. 2511 2512 If `count` is greater than the size of the rest of the `enumerable`, 2513 then this function will reverse the rest of the enumerable. 2514 2515 ## Examples 2516 2517 iex> Enum.reverse_slice([1, 2, 3, 4, 5, 6], 2, 4) 2518 [1, 2, 6, 5, 4, 3] 2519 2520 """ 2521 @spec reverse_slice(t, non_neg_integer, non_neg_integer) :: list 2522 def reverse_slice(enumerable, start_index, count) 2523 when is_integer(start_index) and start_index >= 0 and is_integer(count) and count >= 0 do 2524 list = reverse(enumerable) 2525 length = length(list) 2526 count = Kernel.min(count, length - start_index) 2527 2528 if count > 0 do 2529 reverse_slice(list, length, start_index + count, count, []) 2530 else 2531 :lists.reverse(list) 2532 end 2533 end 2534 2535 @doc """ 2536 Slides a single or multiple elements given by `range_or_single_index` from `enumerable` 2537 to `insertion_index`. 2538 2539 The semantics of the range to be moved match the semantics of `Enum.slice/2`. 2540 Specifically, that means: 2541 2542 * Indices are normalized, meaning that negative indexes will be counted from the end 2543 (for example, -1 means the last element of the enumerable). This will result in *two* 2544 traversals of your enumerable on types like lists that don't provide a constant-time count. 2545 2546 * If the normalized index range's `last` is out of bounds, the range is truncated to the last element. 2547 2548 * If the normalized index range's `first` is out of bounds, the selected range for sliding 2549 will be empty, so you'll get back your input list. 2550 2551 * Decreasing ranges (such as `5..0//1`) also select an empty range to be moved, 2552 so you'll get back your input list. 2553 2554 * Ranges with any step but 1 will raise an error. 2555 2556 ## Examples 2557 2558 # Slide a single element 2559 iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 5, 1) 2560 [:a, :f, :b, :c, :d, :e, :g] 2561 2562 # Slide a range of elements backward 2563 iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 3..5, 1) 2564 [:a, :d, :e, :f, :b, :c, :g] 2565 2566 # Slide a range of elements forward 2567 iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 1..3, 5) 2568 [:a, :e, :f, :b, :c, :d, :g] 2569 2570 # Slide with negative indices (counting from the end) 2571 iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 3..-1//1, 2) 2572 [:a, :b, :d, :e, :f, :g, :c] 2573 iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], -4..-2, 1) 2574 [:a, :d, :e, :f, :b, :c, :g] 2575 2576 # Insert at negative indices (counting from the end) 2577 iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 3, -1) 2578 [:a, :b, :c, :e, :f, :g, :d] 2579 2580 """ 2581 @doc since: "1.13.0" 2582 def slide(enumerable, range_or_single_index, insertion_index) 2583 2584 def slide(enumerable, single_index, insertion_index) when is_integer(single_index) do 2585 slide(enumerable, single_index..single_index, insertion_index) 2586 end 2587 2588 # This matches the behavior of Enum.slice/2 2589 def slide(_, _.._//step = index_range, _insertion_index) when step != 1 do 2590 raise ArgumentError, 2591 "Enum.slide/3 does not accept ranges with custom steps, got: #{inspect(index_range)}" 2592 end 2593 2594 # Normalize negative input ranges like Enum.slice/2 2595 def slide(enumerable, first..last, insertion_index) 2596 when first < 0 or last < 0 or insertion_index < 0 do 2597 count = Enum.count(enumerable) 2598 normalized_first = if first >= 0, do: first, else: first + count 2599 normalized_last = if last >= 0, do: last, else: last + count 2600 2601 normalized_insertion_index = 2602 if insertion_index >= 0, do: insertion_index, else: insertion_index + count 2603 2604 if normalized_first >= 0 and normalized_first < count and 2605 normalized_first != normalized_insertion_index do 2606 normalized_range = normalized_first..normalized_last//1 2607 slide(enumerable, normalized_range, normalized_insertion_index) 2608 else 2609 Enum.to_list(enumerable) 2610 end 2611 end 2612 2613 def slide(enumerable, insertion_index.._, insertion_index) do 2614 Enum.to_list(enumerable) 2615 end 2616 2617 def slide(_, first..last, insertion_index) 2618 when insertion_index > first and insertion_index <= last do 2619 raise "Insertion index for slide must be outside the range being moved " <> 2620 "(tried to insert #{first}..#{last} at #{insertion_index})" 2621 end 2622 2623 # Guarantees at this point: step size == 1 and first <= last and (insertion_index < first or insertion_index > last) 2624 def slide(enumerable, first..last, insertion_index) do 2625 impl = if is_list(enumerable), do: &slide_list_start/4, else: &slide_any/4 2626 2627 cond do 2628 insertion_index <= first -> impl.(enumerable, insertion_index, first, last) 2629 insertion_index > last -> impl.(enumerable, first, last + 1, insertion_index) 2630 end 2631 end 2632 2633 # Takes the range from middle..last and moves it to be in front of index start 2634 defp slide_any(enumerable, start, middle, last) do 2635 # We're going to deal with 4 "chunks" of the enumerable: 2636 # 0. "Head," before the start index 2637 # 1. "Slide back," between start (inclusive) and middle (exclusive) 2638 # 2. "Slide front," between middle (inclusive) and last (inclusive) 2639 # 3. "Tail," after last 2640 # 2641 # But, we're going to accumulate these into only two lists: pre and post. 2642 # We'll reverse-accumulate the head into our pre list, then "slide back" into post, 2643 # then "slide front" into pre, then "tail" into post. 2644 # 2645 # Then at the end, we're going to reassemble and reverse them, and end up with the 2646 # chunks in the correct order. 2647 {_size, pre, post} = 2648 Enum.reduce(enumerable, {0, [], []}, fn item, {index, pre, post} -> 2649 {pre, post} = 2650 cond do 2651 index < start -> {[item | pre], post} 2652 index >= start and index < middle -> {pre, [item | post]} 2653 index >= middle and index <= last -> {[item | pre], post} 2654 true -> {pre, [item | post]} 2655 end 2656 2657 {index + 1, pre, post} 2658 end) 2659 2660 :lists.reverse(pre, :lists.reverse(post)) 2661 end 2662 2663 # Like slide_any/4 above, this optimized implementation of slide for lists depends 2664 # on the indices being sorted such that we're moving middle..last to be in front of start. 2665 defp slide_list_start([h | t], start, middle, last) 2666 when start > 0 and start <= middle and middle <= last do 2667 [h | slide_list_start(t, start - 1, middle - 1, last - 1)] 2668 end 2669 2670 defp slide_list_start(list, 0, middle, last), do: slide_list_middle(list, middle, last, []) 2671 2672 defp slide_list_middle([h | t], middle, last, acc) when middle > 0 do 2673 slide_list_middle(t, middle - 1, last - 1, [h | acc]) 2674 end 2675 2676 defp slide_list_middle(list, 0, last, start_to_middle) do 2677 {slid_range, tail} = slide_list_last(list, last + 1, []) 2678 slid_range ++ :lists.reverse(start_to_middle, tail) 2679 end 2680 2681 # You asked for a middle index off the end of the list... you get what we've got 2682 defp slide_list_middle([], _, _, acc) do 2683 :lists.reverse(acc) 2684 end 2685 2686 defp slide_list_last([h | t], last, acc) when last > 0 do 2687 slide_list_last(t, last - 1, [h | acc]) 2688 end 2689 2690 defp slide_list_last(rest, 0, acc) do 2691 {:lists.reverse(acc), rest} 2692 end 2693 2694 defp slide_list_last([], _, acc) do 2695 {:lists.reverse(acc), []} 2696 end 2697 2698 @doc """ 2699 Applies the given function to each element in the `enumerable`, 2700 storing the result in a list and passing it as the accumulator 2701 for the next computation. Uses the first element in the `enumerable` 2702 as the starting value. 2703 2704 ## Examples 2705 2706 iex> Enum.scan(1..5, &(&1 + &2)) 2707 [1, 3, 6, 10, 15] 2708 2709 """ 2710 @spec scan(t, (element, any -> any)) :: list 2711 def scan(enumerable, fun) 2712 2713 def scan([], _fun), do: [] 2714 2715 def scan([elem | rest], fun) do 2716 scanned = scan_list(rest, elem, fun) 2717 [elem | scanned] 2718 end 2719 2720 def scan(enumerable, fun) do 2721 {res, _} = reduce(enumerable, {[], :first}, R.scan2(fun)) 2722 :lists.reverse(res) 2723 end 2724 2725 @doc """ 2726 Applies the given function to each element in the `enumerable`, 2727 storing the result in a list and passing it as the accumulator 2728 for the next computation. Uses the given `acc` as the starting value. 2729 2730 ## Examples 2731 2732 iex> Enum.scan(1..5, 0, &(&1 + &2)) 2733 [1, 3, 6, 10, 15] 2734 2735 """ 2736 @spec scan(t, any, (element, any -> any)) :: list 2737 def scan(enumerable, acc, fun) when is_list(enumerable) do 2738 scan_list(enumerable, acc, fun) 2739 end 2740 2741 def scan(enumerable, acc, fun) do 2742 {res, _} = reduce(enumerable, {[], acc}, R.scan3(fun)) 2743 :lists.reverse(res) 2744 end 2745 2746 @doc """ 2747 Returns a list with the elements of `enumerable` shuffled. 2748 2749 This function uses Erlang's [`:rand` module](`:rand`) to calculate 2750 the random value. Check its documentation for setting a 2751 different random algorithm or a different seed. 2752 2753 ## Examples 2754 2755 The examples below use the `:exsss` pseudorandom algorithm since it's 2756 the default from Erlang/OTP 22: 2757 2758 # Although not necessary, let's seed the random algorithm 2759 iex> :rand.seed(:exsss, {1, 2, 3}) 2760 iex> Enum.shuffle([1, 2, 3]) 2761 [3, 2, 1] 2762 iex> Enum.shuffle([1, 2, 3]) 2763 [2, 1, 3] 2764 2765 """ 2766 @spec shuffle(t) :: list 2767 def shuffle(enumerable) do 2768 randomized = 2769 reduce(enumerable, [], fn x, acc -> 2770 [{:rand.uniform(), x} | acc] 2771 end) 2772 2773 shuffle_unwrap(:lists.keysort(1, randomized), []) 2774 end 2775 2776 @doc """ 2777 Returns a subset list of the given `enumerable` by `index_range`. 2778 2779 `index_range` must be a `Range`. Given an `enumerable`, it drops 2780 elements before `index_range.first` (zero-base), then it takes elements 2781 until element `index_range.last` (inclusively). 2782 2783 Indexes are normalized, meaning that negative indexes will be counted 2784 from the end (for example, `-1` means the last element of the `enumerable`). 2785 2786 If `index_range.last` is out of bounds, then it is assigned as the index 2787 of the last element. 2788 2789 If the normalized `index_range.first` is out of bounds of the given 2790 `enumerable`, or this one is greater than the normalized `index_range.last`, 2791 then `[]` is returned. 2792 2793 ## Examples 2794 2795 iex> Enum.slice(1..100, 5..10) 2796 [6, 7, 8, 9, 10, 11] 2797 2798 iex> Enum.slice(1..10, 5..20) 2799 [6, 7, 8, 9, 10] 2800 2801 # last five elements (negative indexes) 2802 iex> Enum.slice(1..30, -5..-1) 2803 [26, 27, 28, 29, 30] 2804 2805 For ranges where `start > stop`, you need to explicit 2806 mark them as increasing: 2807 2808 iex> Enum.slice(1..30, 25..-1//1) 2809 [26, 27, 28, 29, 30] 2810 2811 If values are out of bounds, it returns an empty list: 2812 2813 iex> Enum.slice(1..10, 11..20) 2814 [] 2815 2816 # first is greater than last 2817 iex> Enum.slice(1..10, 6..5) 2818 [] 2819 2820 """ 2821 @doc since: "1.6.0" 2822 @spec slice(t, Range.t()) :: list 2823 def slice(enumerable, first..last//step = index_range) do 2824 # TODO: Deprecate negative steps on Elixir v1.16 2825 # TODO: There are two features we can add to slicing ranges: 2826 # 1. We can allow the step to be any positive number 2827 # 2. We can allow slice and reverse at the same time. However, we can't 2828 # implement so right now. First we will have to raise if a decreasing 2829 # range is given on Elixir v2.0. 2830 if step == 1 or (step == -1 and first > last) do 2831 slice_range(enumerable, first, last) 2832 else 2833 raise ArgumentError, 2834 "Enum.slice/2 does not accept ranges with custom steps, got: #{inspect(index_range)}" 2835 end 2836 end 2837 2838 # TODO: Remove me on v2.0 2839 def slice(enumerable, %{__struct__: Range, first: first, last: last} = index_range) do 2840 step = if first <= last, do: 1, else: -1 2841 slice(enumerable, Map.put(index_range, :step, step)) 2842 end 2843 2844 defp slice_range(enumerable, first, last) when last >= first and last >= 0 and first >= 0 do 2845 slice_any(enumerable, first, last - first + 1) 2846 end 2847 2848 defp slice_range(enumerable, first, last) do 2849 {count, fun} = slice_count_and_fun(enumerable) 2850 first = if first >= 0, do: first, else: first + count 2851 last = if last >= 0, do: last, else: last + count 2852 amount = last - first + 1 2853 2854 if first >= 0 and first < count and amount > 0 do 2855 fun.(first, Kernel.min(amount, count - first)) 2856 else 2857 [] 2858 end 2859 end 2860 2861 @doc """ 2862 Returns a subset list of the given `enumerable`, from `start_index` (zero-based) 2863 with `amount` number of elements if available. 2864 2865 Given an `enumerable`, it drops elements right before element `start_index`; 2866 then, it takes `amount` of elements, returning as many elements as possible if 2867 there are not enough elements. 2868 2869 A negative `start_index` can be passed, which means the `enumerable` is 2870 enumerated once and the index is counted from the end (for example, 2871 `-1` starts slicing from the last element). 2872 2873 It returns `[]` if `amount` is `0` or if `start_index` is out of bounds. 2874 2875 ## Examples 2876 2877 iex> Enum.slice(1..100, 5, 10) 2878 [6, 7, 8, 9, 10, 11, 12, 13, 14, 15] 2879 2880 # amount to take is greater than the number of elements 2881 iex> Enum.slice(1..10, 5, 100) 2882 [6, 7, 8, 9, 10] 2883 2884 iex> Enum.slice(1..10, 5, 0) 2885 [] 2886 2887 # using a negative start index 2888 iex> Enum.slice(1..10, -6, 3) 2889 [5, 6, 7] 2890 2891 # out of bound start index (positive) 2892 iex> Enum.slice(1..10, 10, 5) 2893 [] 2894 2895 # out of bound start index (negative) 2896 iex> Enum.slice(1..10, -11, 5) 2897 [] 2898 2899 """ 2900 @spec slice(t, index, non_neg_integer) :: list 2901 def slice(_enumerable, start_index, 0) when is_integer(start_index), do: [] 2902 2903 def slice(enumerable, start_index, amount) 2904 when is_integer(start_index) and is_integer(amount) and amount >= 0 do 2905 slice_any(enumerable, start_index, amount) 2906 end 2907 2908 @doc """ 2909 Sorts the `enumerable` according to Erlang's term ordering. 2910 2911 This function uses the merge sort algorithm. Do not use this 2912 function to sort structs, see `sort/2` for more information. 2913 2914 ## Examples 2915 2916 iex> Enum.sort([3, 2, 1]) 2917 [1, 2, 3] 2918 2919 """ 2920 @spec sort(t) :: list 2921 def sort(enumerable) when is_list(enumerable) do 2922 :lists.sort(enumerable) 2923 end 2924 2925 def sort(enumerable) do 2926 sort(enumerable, &(&1 <= &2)) 2927 end 2928 2929 @doc """ 2930 Sorts the `enumerable` by the given function. 2931 2932 This function uses the merge sort algorithm. The given function should compare 2933 two arguments, and return `true` if the first argument precedes or is in the 2934 same place as the second one. 2935 2936 ## Examples 2937 2938 iex> Enum.sort([1, 2, 3], &(&1 >= &2)) 2939 [3, 2, 1] 2940 2941 The sorting algorithm will be stable as long as the given function 2942 returns `true` for values considered equal: 2943 2944 iex> Enum.sort(["some", "kind", "of", "monster"], &(byte_size(&1) <= byte_size(&2))) 2945 ["of", "some", "kind", "monster"] 2946 2947 If the function does not return `true` for equal values, the sorting 2948 is not stable and the order of equal terms may be shuffled. 2949 For example: 2950 2951 iex> Enum.sort(["some", "kind", "of", "monster"], &(byte_size(&1) < byte_size(&2))) 2952 ["of", "kind", "some", "monster"] 2953 2954 ## Ascending and descending 2955 2956 `sort/2` allows a developer to pass `:asc` or `:desc` as the sorting 2957 function, which is a convenience for `<=/2` and `>=/2` respectively. 2958 2959 iex> Enum.sort([2, 3, 1], :asc) 2960 [1, 2, 3] 2961 iex> Enum.sort([2, 3, 1], :desc) 2962 [3, 2, 1] 2963 2964 ## Sorting structs 2965 2966 Do not use `</2`, `<=/2`, `>/2`, `>=/2` and friends when sorting structs. 2967 That's because the built-in operators above perform structural comparison 2968 and not a semantic one. Imagine we sort the following list of dates: 2969 2970 iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]] 2971 iex> Enum.sort(dates) 2972 [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]] 2973 2974 Note that the returned result is incorrect, because `sort/1` by default uses 2975 `<=/2`, which will compare their structure. When comparing structures, the 2976 fields are compared in alphabetical order, which means the dates above will 2977 be compared by `day`, `month` and then `year`, which is the opposite of what 2978 we want. 2979 2980 For this reason, most structs provide a "compare" function, such as 2981 `Date.compare/2`, which receives two structs and returns `:lt` (less-than), 2982 `:eq` (equal to), and `:gt` (greater-than). If you pass a module as the 2983 sorting function, Elixir will automatically use the `compare/2` function 2984 of said module: 2985 2986 iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]] 2987 iex> Enum.sort(dates, Date) 2988 [~D[2019-01-01], ~D[2019-06-06], ~D[2020-03-02]] 2989 2990 To retrieve all dates in descending order, you can wrap the module in 2991 a tuple with `:asc` or `:desc` as first element: 2992 2993 iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]] 2994 iex> Enum.sort(dates, {:asc, Date}) 2995 [~D[2019-01-01], ~D[2019-06-06], ~D[2020-03-02]] 2996 iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]] 2997 iex> Enum.sort(dates, {:desc, Date}) 2998 [~D[2020-03-02], ~D[2019-06-06], ~D[2019-01-01]] 2999 3000 """ 3001 @spec sort( 3002 t, 3003 (element, element -> boolean) | :asc | :desc | module() | {:asc | :desc, module()} 3004 ) :: list 3005 def sort(enumerable, fun) when is_list(enumerable) do 3006 :lists.sort(to_sort_fun(fun), enumerable) 3007 end 3008 3009 def sort(enumerable, fun) do 3010 fun = to_sort_fun(fun) 3011 3012 reduce(enumerable, [], &sort_reducer(&1, &2, fun)) 3013 |> sort_terminator(fun) 3014 end 3015 3016 defp to_sort_fun(sorter) when is_function(sorter, 2), do: sorter 3017 defp to_sort_fun(:asc), do: &<=/2 3018 defp to_sort_fun(:desc), do: &>=/2 3019 defp to_sort_fun(module) when is_atom(module), do: &(module.compare(&1, &2) != :gt) 3020 defp to_sort_fun({:asc, module}) when is_atom(module), do: &(module.compare(&1, &2) != :gt) 3021 defp to_sort_fun({:desc, module}) when is_atom(module), do: &(module.compare(&1, &2) != :lt) 3022 3023 @doc """ 3024 Sorts the mapped results of the `enumerable` according to the provided `sorter` 3025 function. 3026 3027 This function maps each element of the `enumerable` using the 3028 provided `mapper` function. The enumerable is then sorted by 3029 the mapped elements using the `sorter` function, which defaults 3030 to `Kernel.<=/2`. 3031 3032 `sort_by/3` differs from `sort/2` in that it only calculates the 3033 comparison value for each element in the enumerable once instead of 3034 once for each element in each comparison. If the same function is 3035 being called on both elements, it's more efficient to use `sort_by/3`. 3036 3037 ## Examples 3038 3039 Using the default `sorter` of `<=/2`: 3040 3041 iex> Enum.sort_by(["some", "kind", "of", "monster"], &byte_size/1) 3042 ["of", "some", "kind", "monster"] 3043 3044 Sorting by multiple properties - first by size, then by first letter 3045 (this takes advantage of the fact that tuples are compared element-by-element): 3046 3047 iex> Enum.sort_by(["some", "kind", "of", "monster"], &{byte_size(&1), String.first(&1)}) 3048 ["of", "kind", "some", "monster"] 3049 3050 Similar to `sort/2`, you can pass a custom sorter: 3051 3052 iex> Enum.sort_by(["some", "kind", "of", "monster"], &byte_size/1, &>=/2) 3053 ["monster", "some", "kind", "of"] 3054 3055 Or use `:asc` and `:desc`: 3056 3057 iex> Enum.sort_by(["some", "kind", "of", "monster"], &byte_size/1, :desc) 3058 ["monster", "some", "kind", "of"] 3059 3060 As in `sort/2`, avoid using the default sorting function to sort structs, as by default 3061 it performs structural comparison instead of a semantic one. In such cases, 3062 you shall pass a sorting function as third element or any module that implements 3063 a `compare/2` function. For example, to sort users by their birthday in both 3064 ascending and descending order respectively: 3065 3066 iex> users = [ 3067 ...> %{name: "Ellis", birthday: ~D[1943-05-11]}, 3068 ...> %{name: "Lovelace", birthday: ~D[1815-12-10]}, 3069 ...> %{name: "Turing", birthday: ~D[1912-06-23]} 3070 ...> ] 3071 iex> Enum.sort_by(users, &(&1.birthday), Date) 3072 [ 3073 %{name: "Lovelace", birthday: ~D[1815-12-10]}, 3074 %{name: "Turing", birthday: ~D[1912-06-23]}, 3075 %{name: "Ellis", birthday: ~D[1943-05-11]} 3076 ] 3077 iex> Enum.sort_by(users, &(&1.birthday), {:desc, Date}) 3078 [ 3079 %{name: "Ellis", birthday: ~D[1943-05-11]}, 3080 %{name: "Turing", birthday: ~D[1912-06-23]}, 3081 %{name: "Lovelace", birthday: ~D[1815-12-10]} 3082 ] 3083 3084 """ 3085 @spec sort_by( 3086 t, 3087 (element -> mapped_element), 3088 (element, element -> boolean) | :asc | :desc | module() | {:asc | :desc, module()} 3089 ) :: 3090 list 3091 when mapped_element: element 3092 def sort_by(enumerable, mapper, sorter \\ &<=/2) do 3093 enumerable 3094 |> map(&{&1, mapper.(&1)}) 3095 |> sort(to_sort_by_fun(sorter)) 3096 |> map(&elem(&1, 0)) 3097 end 3098 3099 defp to_sort_by_fun(sorter) when is_function(sorter, 2), 3100 do: &sorter.(elem(&1, 1), elem(&2, 1)) 3101 3102 defp to_sort_by_fun(:asc), 3103 do: &(elem(&1, 1) <= elem(&2, 1)) 3104 3105 defp to_sort_by_fun(:desc), 3106 do: &(elem(&1, 1) >= elem(&2, 1)) 3107 3108 defp to_sort_by_fun(module) when is_atom(module), 3109 do: &(module.compare(elem(&1, 1), elem(&2, 1)) != :gt) 3110 3111 defp to_sort_by_fun({:asc, module}) when is_atom(module), 3112 do: &(module.compare(elem(&1, 1), elem(&2, 1)) != :gt) 3113 3114 defp to_sort_by_fun({:desc, module}) when is_atom(module), 3115 do: &(module.compare(elem(&1, 1), elem(&2, 1)) != :lt) 3116 3117 @doc """ 3118 Splits the `enumerable` into two enumerables, leaving `count` 3119 elements in the first one. 3120 3121 If `count` is a negative number, it starts counting from the 3122 back to the beginning of the `enumerable`. 3123 3124 Be aware that a negative `count` implies the `enumerable` 3125 will be enumerated twice: once to calculate the position, and 3126 a second time to do the actual splitting. 3127 3128 ## Examples 3129 3130 iex> Enum.split([1, 2, 3], 2) 3131 {[1, 2], [3]} 3132 3133 iex> Enum.split([1, 2, 3], 10) 3134 {[1, 2, 3], []} 3135 3136 iex> Enum.split([1, 2, 3], 0) 3137 {[], [1, 2, 3]} 3138 3139 iex> Enum.split([1, 2, 3], -1) 3140 {[1, 2], [3]} 3141 3142 iex> Enum.split([1, 2, 3], -5) 3143 {[], [1, 2, 3]} 3144 3145 """ 3146 @spec split(t, integer) :: {list, list} 3147 def split(enumerable, count) when is_list(enumerable) and is_integer(count) and count >= 0 do 3148 split_list(enumerable, count, []) 3149 end 3150 3151 def split(enumerable, count) when is_integer(count) and count >= 0 do 3152 {_, list1, list2} = 3153 reduce(enumerable, {count, [], []}, fn entry, {counter, acc1, acc2} -> 3154 if counter > 0 do 3155 {counter - 1, [entry | acc1], acc2} 3156 else 3157 {counter, acc1, [entry | acc2]} 3158 end 3159 end) 3160 3161 {:lists.reverse(list1), :lists.reverse(list2)} 3162 end 3163 3164 def split(enumerable, count) when is_integer(count) and count < 0 do 3165 split_reverse_list(reverse(enumerable), -count, []) 3166 end 3167 3168 @doc """ 3169 Splits enumerable in two at the position of the element for which 3170 `fun` returns a falsy value (`false` or `nil`) for the first time. 3171 3172 It returns a two-element tuple with two lists of elements. 3173 The element that triggered the split is part of the second list. 3174 3175 ## Examples 3176 3177 iex> Enum.split_while([1, 2, 3, 4], fn x -> x < 3 end) 3178 {[1, 2], [3, 4]} 3179 3180 iex> Enum.split_while([1, 2, 3, 4], fn x -> x < 0 end) 3181 {[], [1, 2, 3, 4]} 3182 3183 iex> Enum.split_while([1, 2, 3, 4], fn x -> x > 0 end) 3184 {[1, 2, 3, 4], []} 3185 3186 """ 3187 @spec split_while(t, (element -> as_boolean(term))) :: {list, list} 3188 def split_while(enumerable, fun) when is_list(enumerable) do 3189 split_while_list(enumerable, fun, []) 3190 end 3191 3192 def split_while(enumerable, fun) do 3193 {list1, list2} = 3194 reduce(enumerable, {[], []}, fn 3195 entry, {acc1, []} -> 3196 if(fun.(entry), do: {[entry | acc1], []}, else: {acc1, [entry]}) 3197 3198 entry, {acc1, acc2} -> 3199 {acc1, [entry | acc2]} 3200 end) 3201 3202 {:lists.reverse(list1), :lists.reverse(list2)} 3203 end 3204 3205 @doc """ 3206 Returns the sum of all elements. 3207 3208 Raises `ArithmeticError` if `enumerable` contains a non-numeric value. 3209 3210 ## Examples 3211 3212 iex> Enum.sum([1, 2, 3]) 3213 6 3214 3215 iex> Enum.sum(1..10) 3216 55 3217 3218 iex> Enum.sum(1..10//2) 3219 25 3220 3221 """ 3222 @spec sum(t) :: number 3223 def sum(enumerable) 3224 3225 def sum(first..last//step = range) do 3226 range 3227 |> Range.size() 3228 |> Kernel.*(first + last - rem(last - first, step)) 3229 |> div(2) 3230 end 3231 3232 def sum(enumerable) do 3233 reduce(enumerable, 0, &+/2) 3234 end 3235 3236 @doc """ 3237 Returns the product of all elements. 3238 3239 Raises `ArithmeticError` if `enumerable` contains a non-numeric value. 3240 3241 ## Examples 3242 3243 iex> Enum.product([]) 3244 1 3245 iex> Enum.product([2, 3, 4]) 3246 24 3247 iex> Enum.product([2.0, 3.0, 4.0]) 3248 24.0 3249 3250 """ 3251 @doc since: "1.12.0" 3252 @spec product(t) :: number 3253 def product(enumerable) do 3254 reduce(enumerable, 1, &*/2) 3255 end 3256 3257 @doc """ 3258 Takes an `amount` of elements from the beginning or the end of the `enumerable`. 3259 3260 If a positive `amount` is given, it takes the `amount` elements from the 3261 beginning of the `enumerable`. 3262 3263 If a negative `amount` is given, the `amount` of elements will be taken from the end. 3264 The `enumerable` will be enumerated once to retrieve the proper index and 3265 the remaining calculation is performed from the end. 3266 3267 If amount is `0`, it returns `[]`. 3268 3269 ## Examples 3270 3271 iex> Enum.take([1, 2, 3], 2) 3272 [1, 2] 3273 3274 iex> Enum.take([1, 2, 3], 10) 3275 [1, 2, 3] 3276 3277 iex> Enum.take([1, 2, 3], 0) 3278 [] 3279 3280 iex> Enum.take([1, 2, 3], -1) 3281 [3] 3282 3283 """ 3284 @spec take(t, integer) :: list 3285 def take(enumerable, amount) 3286 3287 def take(_enumerable, 0), do: [] 3288 3289 def take(enumerable, amount) 3290 when is_list(enumerable) and is_integer(amount) and amount > 0 do 3291 take_list(enumerable, amount) 3292 end 3293 3294 def take(enumerable, amount) when is_integer(amount) and amount > 0 do 3295 {_, {res, _}} = 3296 Enumerable.reduce(enumerable, {:cont, {[], amount}}, fn entry, {list, n} -> 3297 case n do 3298 1 -> {:halt, {[entry | list], n - 1}} 3299 _ -> {:cont, {[entry | list], n - 1}} 3300 end 3301 end) 3302 3303 :lists.reverse(res) 3304 end 3305 3306 def take(enumerable, amount) when is_integer(amount) and amount < 0 do 3307 {count, fun} = slice_count_and_fun(enumerable) 3308 first = Kernel.max(amount + count, 0) 3309 fun.(first, count - first) 3310 end 3311 3312 @doc """ 3313 Returns a list of every `nth` element in the `enumerable`, 3314 starting with the first element. 3315 3316 The first element is always included, unless `nth` is 0. 3317 3318 The second argument specifying every `nth` element must be a non-negative 3319 integer. 3320 3321 ## Examples 3322 3323 iex> Enum.take_every(1..10, 2) 3324 [1, 3, 5, 7, 9] 3325 3326 iex> Enum.take_every(1..10, 0) 3327 [] 3328 3329 iex> Enum.take_every([1, 2, 3], 1) 3330 [1, 2, 3] 3331 3332 """ 3333 @spec take_every(t, non_neg_integer) :: list 3334 def take_every(enumerable, nth) 3335 3336 def take_every(enumerable, 1), do: to_list(enumerable) 3337 def take_every(_enumerable, 0), do: [] 3338 def take_every([], nth) when is_integer(nth) and nth > 1, do: [] 3339 3340 def take_every(enumerable, nth) when is_integer(nth) and nth > 1 do 3341 {res, _} = reduce(enumerable, {[], :first}, R.take_every(nth)) 3342 :lists.reverse(res) 3343 end 3344 3345 @doc """ 3346 Takes `count` random elements from `enumerable`. 3347 3348 Note that this function will traverse the whole `enumerable` to 3349 get the random sublist. 3350 3351 See `random/1` for notes on implementation and random seed. 3352 3353 ## Examples 3354 3355 # Although not necessary, let's seed the random algorithm 3356 iex> :rand.seed(:exsss, {1, 2, 3}) 3357 iex> Enum.take_random(1..10, 2) 3358 [3, 1] 3359 iex> Enum.take_random(?a..?z, 5) 3360 'mikel' 3361 3362 """ 3363 @spec take_random(t, non_neg_integer) :: list 3364 def take_random(enumerable, count) 3365 def take_random(_enumerable, 0), do: [] 3366 3367 def take_random([], _), do: [] 3368 def take_random([h | t], 1), do: take_random_list_one(t, h, 1) 3369 3370 def take_random(enumerable, 1) do 3371 enumerable 3372 |> reduce([], fn 3373 x, [current | index] -> 3374 if :rand.uniform(index + 1) == 1 do 3375 [x | index + 1] 3376 else 3377 [current | index + 1] 3378 end 3379 3380 x, [] -> 3381 [x | 1] 3382 end) 3383 |> case do 3384 [] -> [] 3385 [current | _index] -> [current] 3386 end 3387 end 3388 3389 def take_random(enumerable, count) when is_integer(count) and count in 0..128 do 3390 sample = Tuple.duplicate(nil, count) 3391 3392 reducer = fn elem, {idx, sample} -> 3393 jdx = random_integer(0, idx) 3394 3395 cond do 3396 idx < count -> 3397 value = elem(sample, jdx) 3398 {idx + 1, put_elem(sample, idx, value) |> put_elem(jdx, elem)} 3399 3400 jdx < count -> 3401 {idx + 1, put_elem(sample, jdx, elem)} 3402 3403 true -> 3404 {idx + 1, sample} 3405 end 3406 end 3407 3408 {size, sample} = reduce(enumerable, {0, sample}, reducer) 3409 sample |> Tuple.to_list() |> take(Kernel.min(count, size)) 3410 end 3411 3412 def take_random(enumerable, count) when is_integer(count) and count >= 0 do 3413 reducer = fn elem, {idx, sample} -> 3414 jdx = random_integer(0, idx) 3415 3416 cond do 3417 idx < count -> 3418 value = Map.get(sample, jdx) 3419 {idx + 1, Map.put(sample, idx, value) |> Map.put(jdx, elem)} 3420 3421 jdx < count -> 3422 {idx + 1, Map.put(sample, jdx, elem)} 3423 3424 true -> 3425 {idx + 1, sample} 3426 end 3427 end 3428 3429 {size, sample} = reduce(enumerable, {0, %{}}, reducer) 3430 take_random(sample, Kernel.min(count, size), []) 3431 end 3432 3433 defp take_random(_sample, 0, acc), do: acc 3434 3435 defp take_random(sample, position, acc) do 3436 position = position - 1 3437 take_random(sample, position, [Map.get(sample, position) | acc]) 3438 end 3439 3440 defp take_random_list_one([h | t], current, index) do 3441 if :rand.uniform(index + 1) == 1 do 3442 take_random_list_one(t, h, index + 1) 3443 else 3444 take_random_list_one(t, current, index + 1) 3445 end 3446 end 3447 3448 defp take_random_list_one([], current, _), do: [current] 3449 3450 @doc """ 3451 Takes the elements from the beginning of the `enumerable` while `fun` returns 3452 a truthy value. 3453 3454 ## Examples 3455 3456 iex> Enum.take_while([1, 2, 3], fn x -> x < 3 end) 3457 [1, 2] 3458 3459 """ 3460 @spec take_while(t, (element -> as_boolean(term))) :: list 3461 def take_while(enumerable, fun) when is_list(enumerable) do 3462 take_while_list(enumerable, fun) 3463 end 3464 3465 def take_while(enumerable, fun) do 3466 {_, res} = 3467 Enumerable.reduce(enumerable, {:cont, []}, fn entry, acc -> 3468 if fun.(entry) do 3469 {:cont, [entry | acc]} 3470 else 3471 {:halt, acc} 3472 end 3473 end) 3474 3475 :lists.reverse(res) 3476 end 3477 3478 @doc """ 3479 Converts `enumerable` to a list. 3480 3481 ## Examples 3482 3483 iex> Enum.to_list(1..3) 3484 [1, 2, 3] 3485 3486 """ 3487 @spec to_list(t) :: [element] 3488 def to_list(enumerable) when is_list(enumerable), do: enumerable 3489 def to_list(%_{} = enumerable), do: reverse(enumerable) |> :lists.reverse() 3490 def to_list(%{} = enumerable), do: Map.to_list(enumerable) 3491 def to_list(enumerable), do: reverse(enumerable) |> :lists.reverse() 3492 3493 @doc """ 3494 Enumerates the `enumerable`, removing all duplicated elements. 3495 3496 ## Examples 3497 3498 iex> Enum.uniq([1, 2, 3, 3, 2, 1]) 3499 [1, 2, 3] 3500 3501 """ 3502 @spec uniq(t) :: list 3503 def uniq(enumerable) do 3504 uniq_by(enumerable, fn x -> x end) 3505 end 3506 3507 @doc false 3508 @deprecated "Use Enum.uniq_by/2 instead" 3509 def uniq(enumerable, fun) do 3510 uniq_by(enumerable, fun) 3511 end 3512 3513 @doc """ 3514 Enumerates the `enumerable`, by removing the elements for which 3515 function `fun` returned duplicate elements. 3516 3517 The function `fun` maps every element to a term. Two elements are 3518 considered duplicates if the return value of `fun` is equal for 3519 both of them. 3520 3521 The first occurrence of each element is kept. 3522 3523 ## Example 3524 3525 iex> Enum.uniq_by([{1, :x}, {2, :y}, {1, :z}], fn {x, _} -> x end) 3526 [{1, :x}, {2, :y}] 3527 3528 iex> Enum.uniq_by([a: {:tea, 2}, b: {:tea, 2}, c: {:coffee, 1}], fn {_, y} -> y end) 3529 [a: {:tea, 2}, c: {:coffee, 1}] 3530 3531 """ 3532 @spec uniq_by(t, (element -> term)) :: list 3533 3534 def uniq_by(enumerable, fun) when is_list(enumerable) do 3535 uniq_list(enumerable, %{}, fun) 3536 end 3537 3538 def uniq_by(enumerable, fun) do 3539 {list, _} = reduce(enumerable, {[], %{}}, R.uniq_by(fun)) 3540 :lists.reverse(list) 3541 end 3542 3543 @doc """ 3544 Opposite of `zip/2`. Extracts two-element tuples from the 3545 given `enumerable` and groups them together. 3546 3547 It takes an `enumerable` with elements being two-element tuples and returns 3548 a tuple with two lists, each of which is formed by the first and 3549 second element of each tuple, respectively. 3550 3551 This function fails unless `enumerable` is or can be converted into a 3552 list of tuples with *exactly* two elements in each tuple. 3553 3554 ## Examples 3555 3556 iex> Enum.unzip([{:a, 1}, {:b, 2}, {:c, 3}]) 3557 {[:a, :b, :c], [1, 2, 3]} 3558 3559 iex> Enum.unzip(%{a: 1, b: 2}) 3560 {[:a, :b], [1, 2]} 3561 3562 """ 3563 @spec unzip(t) :: {[element], [element]} 3564 3565 def unzip([_ | _] = list) do 3566 :lists.reverse(list) |> unzip([], []) 3567 end 3568 3569 def unzip([]) do 3570 {[], []} 3571 end 3572 3573 def unzip(enumerable) do 3574 {list1, list2} = 3575 reduce(enumerable, {[], []}, fn {el1, el2}, {list1, list2} -> 3576 {[el1 | list1], [el2 | list2]} 3577 end) 3578 3579 {:lists.reverse(list1), :lists.reverse(list2)} 3580 end 3581 3582 defp unzip([{el1, el2} | reversed_list], list1, list2) do 3583 unzip(reversed_list, [el1 | list1], [el2 | list2]) 3584 end 3585 3586 defp unzip([], list1, list2) do 3587 {list1, list2} 3588 end 3589 3590 @doc """ 3591 Returns the `enumerable` with each element wrapped in a tuple 3592 alongside its index. 3593 3594 May receive a function or an integer offset. 3595 3596 If an `offset` is given, it will index from the given offset instead of from 3597 zero. 3598 3599 If a `function` is given, it will index by invoking the function for each 3600 element and index (zero-based) of the enumerable. 3601 3602 ## Examples 3603 3604 iex> Enum.with_index([:a, :b, :c]) 3605 [a: 0, b: 1, c: 2] 3606 3607 iex> Enum.with_index([:a, :b, :c], 3) 3608 [a: 3, b: 4, c: 5] 3609 3610 iex> Enum.with_index([:a, :b, :c], fn element, index -> {index, element} end) 3611 [{0, :a}, {1, :b}, {2, :c}] 3612 3613 """ 3614 @spec with_index(t, integer) :: [{term, integer}] 3615 @spec with_index(t, (element, index -> value)) :: [value] when value: any 3616 def with_index(enumerable, fun_or_offset \\ 0) 3617 3618 def with_index(enumerable, offset) when is_integer(offset) do 3619 enumerable 3620 |> map_reduce(offset, fn x, i -> {{x, i}, i + 1} end) 3621 |> elem(0) 3622 end 3623 3624 def with_index(enumerable, fun) when is_function(fun, 2) do 3625 enumerable 3626 |> map_reduce(0, fn x, i -> {fun.(x, i), i + 1} end) 3627 |> elem(0) 3628 end 3629 3630 @doc """ 3631 Zips corresponding elements from two enumerables into a list 3632 of tuples. 3633 3634 The zipping finishes as soon as either enumerable completes. 3635 3636 ## Examples 3637 3638 iex> Enum.zip([1, 2, 3], [:a, :b, :c]) 3639 [{1, :a}, {2, :b}, {3, :c}] 3640 3641 iex> Enum.zip([1, 2, 3, 4, 5], [:a, :b, :c]) 3642 [{1, :a}, {2, :b}, {3, :c}] 3643 3644 """ 3645 @spec zip(t, t) :: [{any, any}] 3646 def zip(enumerable1, enumerable2) when is_list(enumerable1) and is_list(enumerable2) do 3647 zip_list(enumerable1, enumerable2, []) 3648 end 3649 3650 def zip(enumerable1, enumerable2) do 3651 zip([enumerable1, enumerable2]) 3652 end 3653 3654 @doc """ 3655 Zips corresponding elements from a finite collection of enumerables 3656 into a list of tuples. 3657 3658 The zipping finishes as soon as any enumerable in the given collection completes. 3659 3660 ## Examples 3661 3662 iex> Enum.zip([[1, 2, 3], [:a, :b, :c], ["foo", "bar", "baz"]]) 3663 [{1, :a, "foo"}, {2, :b, "bar"}, {3, :c, "baz"}] 3664 3665 iex> Enum.zip([[1, 2, 3, 4, 5], [:a, :b, :c]]) 3666 [{1, :a}, {2, :b}, {3, :c}] 3667 3668 """ 3669 @doc since: "1.4.0" 3670 @spec zip(enumerables) :: [tuple()] when enumerables: [t()] | t() 3671 def zip([]), do: [] 3672 3673 def zip(enumerables) do 3674 zip_reduce(enumerables, [], &[List.to_tuple(&1) | &2]) 3675 |> :lists.reverse() 3676 end 3677 3678 @doc """ 3679 Zips corresponding elements from two enumerables into a list, transforming them with 3680 the `zip_fun` function as it goes. 3681 3682 The corresponding elements from each collection are passed to the provided 2-arity `zip_fun` 3683 function in turn. Returns a list that contains the result of calling `zip_fun` for each pair of 3684 elements. 3685 3686 The zipping finishes as soon as either enumerable runs out of elements. 3687 3688 ## Zipping Maps 3689 3690 It's important to remember that zipping inherently relies on order. 3691 If you zip two lists you get the element at the index from each list in turn. 3692 If we zip two maps together it's tempting to think that you will get the given 3693 key in the left map and the matching key in the right map, but there is no such 3694 guarantee because map keys are not ordered! Consider the following: 3695 3696 left = %{:a => 1, 1 => 3} 3697 right = %{:a => 1, :b => :c} 3698 Enum.zip(left, right) 3699 # [{{1, 3}, {:a, 1}}, {{:a, 1}, {:b, :c}}] 3700 3701 As you can see `:a` does not get paired with `:a`. If this is what you want, 3702 you should use `Map.merge/3`. 3703 3704 ## Examples 3705 3706 iex> Enum.zip_with([1, 2], [3, 4], fn x, y -> x + y end) 3707 [4, 6] 3708 3709 iex> Enum.zip_with([1, 2], [3, 4, 5, 6], fn x, y -> x + y end) 3710 [4, 6] 3711 3712 iex> Enum.zip_with([1, 2, 5, 6], [3, 4], fn x, y -> x + y end) 3713 [4, 6] 3714 3715 """ 3716 @doc since: "1.12.0" 3717 @spec zip_with(t, t, (enum1_elem :: term, enum2_elem :: term -> term)) :: [term] 3718 def zip_with(enumerable1, enumerable2, zip_fun) 3719 when is_list(enumerable1) and is_list(enumerable2) and is_function(zip_fun, 2) do 3720 zip_with_list(enumerable1, enumerable2, zip_fun) 3721 end 3722 3723 def zip_with(enumerable1, enumerable2, zip_fun) when is_function(zip_fun, 2) do 3724 zip_reduce(enumerable1, enumerable2, [], fn l, r, acc -> [zip_fun.(l, r) | acc] end) 3725 |> :lists.reverse() 3726 end 3727 3728 @doc """ 3729 Zips corresponding elements from a finite collection of enumerables 3730 into list, transforming them with the `zip_fun` function as it goes. 3731 3732 The first element from each of the enums in `enumerables` will be put 3733 into a list which is then passed to the 1-arity `zip_fun` function. 3734 Then, the second elements from each of the enums are put into a list 3735 and passed to `zip_fun`, and so on until any one of the enums in 3736 `enumerables` runs out of elements. 3737 3738 Returns a list with all the results of calling `zip_fun`. 3739 3740 ## Examples 3741 3742 iex> Enum.zip_with([[1, 2], [3, 4], [5, 6]], fn [x, y, z] -> x + y + z end) 3743 [9, 12] 3744 3745 iex> Enum.zip_with([[1, 2], [3, 4]], fn [x, y] -> x + y end) 3746 [4, 6] 3747 3748 """ 3749 @doc since: "1.12.0" 3750 @spec zip_with(t, ([term] -> term)) :: [term] 3751 def zip_with([], _fun), do: [] 3752 3753 def zip_with(enumerables, zip_fun) do 3754 zip_reduce(enumerables, [], fn values, acc -> [zip_fun.(values) | acc] end) 3755 |> :lists.reverse() 3756 end 3757 3758 @doc """ 3759 Reduces over two enumerables halting as soon as either enumerable is empty. 3760 3761 In practice, the behaviour provided by this function can be achieved with: 3762 3763 Enum.reduce(Stream.zip(left, right), acc, reducer) 3764 3765 But `zip_reduce/4` exists for convenience purposes. 3766 3767 ## Examples 3768 3769 iex> Enum.zip_reduce([1, 2], [3, 4], 0, fn x, y, acc -> x + y + acc end) 3770 10 3771 3772 iex> Enum.zip_reduce([1, 2], [3, 4], [], fn x, y, acc -> [x + y | acc] end) 3773 [6, 4] 3774 """ 3775 @doc since: "1.12.0" 3776 @spec zip_reduce(t, t, acc, (enum1_elem :: term, enum2_elem :: term, acc -> acc)) :: acc 3777 when acc: term 3778 def zip_reduce(left, right, acc, reducer) 3779 when is_list(left) and is_list(right) and is_function(reducer, 3) do 3780 zip_reduce_list(left, right, acc, reducer) 3781 end 3782 3783 def zip_reduce(left, right, acc, reducer) when is_function(reducer, 3) do 3784 reduce = fn [l, r], acc -> {:cont, reducer.(l, r, acc)} end 3785 Stream.zip_with([left, right], & &1).({:cont, acc}, reduce) |> elem(1) 3786 end 3787 3788 @doc """ 3789 Reduces over all of the given enumerables, halting as soon as any enumerable is 3790 empty. 3791 3792 The reducer will receive 2 args: a list of elements (one from each enum) and the 3793 accumulator. 3794 3795 In practice, the behaviour provided by this function can be achieved with: 3796 3797 Enum.reduce(Stream.zip(enums), acc, reducer) 3798 3799 But `zip_reduce/3` exists for convenience purposes. 3800 3801 ## Examples 3802 3803 iex> enums = [[1, 1], [2, 2], [3, 3]] 3804 ...> Enum.zip_reduce(enums, [], fn elements, acc -> 3805 ...> [List.to_tuple(elements) | acc] 3806 ...> end) 3807 [{1, 2, 3}, {1, 2, 3}] 3808 3809 iex> enums = [[1, 2], %{a: 3, b: 4}, [5, 6]] 3810 ...> Enum.zip_reduce(enums, [], fn elements, acc -> 3811 ...> [List.to_tuple(elements) | acc] 3812 ...> end) 3813 [{2, {:b, 4}, 6}, {1, {:a, 3}, 5}] 3814 """ 3815 @doc since: "1.12.0" 3816 @spec zip_reduce(t, acc, ([term], acc -> acc)) :: acc when acc: term 3817 def zip_reduce([], acc, reducer) when is_function(reducer, 2), do: acc 3818 3819 def zip_reduce(enums, acc, reducer) when is_function(reducer, 2) do 3820 Stream.zip_with(enums, & &1).({:cont, acc}, &{:cont, reducer.(&1, &2)}) |> elem(1) 3821 end 3822 3823 ## Helpers 3824 3825 @compile {:inline, entry_to_string: 1, reduce: 3, reduce_by: 3, reduce_enumerable: 3} 3826 3827 defp entry_to_string(entry) when is_binary(entry), do: entry 3828 defp entry_to_string(entry), do: String.Chars.to_string(entry) 3829 3830 defp aggregate([head | tail], fun, _empty) do 3831 aggregate_list(tail, head, fun) 3832 end 3833 3834 defp aggregate([], _fun, empty) do 3835 empty.() 3836 end 3837 3838 defp aggregate(first..last//step = range, fun, empty) do 3839 case Range.size(range) do 3840 0 -> 3841 empty.() 3842 3843 _ -> 3844 last = last - rem(last - first, step) 3845 3846 case fun.(first, last) do 3847 true -> first 3848 false -> last 3849 end 3850 end 3851 end 3852 3853 defp aggregate(enumerable, fun, empty) do 3854 ref = make_ref() 3855 3856 enumerable 3857 |> reduce(ref, fn 3858 element, ^ref -> 3859 element 3860 3861 element, acc -> 3862 case fun.(acc, element) do 3863 true -> acc 3864 false -> element 3865 end 3866 end) 3867 |> case do 3868 ^ref -> empty.() 3869 result -> result 3870 end 3871 end 3872 3873 defp aggregate_list([head | tail], acc, fun) do 3874 acc = 3875 case fun.(acc, head) do 3876 true -> acc 3877 false -> head 3878 end 3879 3880 aggregate_list(tail, acc, fun) 3881 end 3882 3883 defp aggregate_list([], acc, _fun), do: acc 3884 3885 defp aggregate_by(enumerable, fun, sorter, empty_fallback) do 3886 first_fun = &[&1 | fun.(&1)] 3887 3888 reduce_fun = fn entry, [_ | fun_ref] = old -> 3889 fun_entry = fun.(entry) 3890 3891 case sorter.(fun_ref, fun_entry) do 3892 true -> old 3893 false -> [entry | fun_entry] 3894 end 3895 end 3896 3897 case reduce_by(enumerable, first_fun, reduce_fun) do 3898 :empty -> empty_fallback.() 3899 [entry | _] -> entry 3900 end 3901 end 3902 3903 defp reduce_by([head | tail], first, fun) do 3904 :lists.foldl(fun, first.(head), tail) 3905 end 3906 3907 defp reduce_by([], _first, _fun) do 3908 :empty 3909 end 3910 3911 defp reduce_by(enumerable, first, fun) do 3912 reduce(enumerable, :empty, fn 3913 element, :empty -> first.(element) 3914 element, acc -> fun.(element, acc) 3915 end) 3916 end 3917 3918 defp random_integer(limit, limit) when is_integer(limit) do 3919 limit 3920 end 3921 3922 defp random_integer(lower_limit, upper_limit) when upper_limit < lower_limit do 3923 random_integer(upper_limit, lower_limit) 3924 end 3925 3926 defp random_integer(lower_limit, upper_limit) do 3927 lower_limit + :rand.uniform(upper_limit - lower_limit + 1) - 1 3928 end 3929 3930 ## Implementations 3931 3932 ## all? 3933 3934 defp all_list([h | t]) do 3935 if h do 3936 all_list(t) 3937 else 3938 false 3939 end 3940 end 3941 3942 defp all_list([]) do 3943 true 3944 end 3945 3946 defp all_list([h | t], fun) do 3947 if fun.(h) do 3948 all_list(t, fun) 3949 else 3950 false 3951 end 3952 end 3953 3954 defp all_list([], _) do 3955 true 3956 end 3957 3958 ## any? 3959 3960 defp any_list([h | t]) do 3961 if h do 3962 true 3963 else 3964 any_list(t) 3965 end 3966 end 3967 3968 defp any_list([]) do 3969 false 3970 end 3971 3972 defp any_list([h | t], fun) do 3973 if fun.(h) do 3974 true 3975 else 3976 any_list(t, fun) 3977 end 3978 end 3979 3980 defp any_list([], _) do 3981 false 3982 end 3983 3984 ## concat 3985 3986 defp concat_list([h | t]) when is_list(h), do: h ++ concat_list(t) 3987 defp concat_list([h | t]), do: concat_enum([h | t]) 3988 defp concat_list([]), do: [] 3989 3990 defp concat_enum(enum) do 3991 fun = &[&1 | &2] 3992 enum |> reduce([], &reduce(&1, &2, fun)) |> :lists.reverse() 3993 end 3994 3995 # dedup 3996 3997 defp dedup_list([value | tail], acc) do 3998 acc = 3999 case acc do 4000 [^value | _] -> acc 4001 _ -> [value | acc] 4002 end 4003 4004 dedup_list(tail, acc) 4005 end 4006 4007 defp dedup_list([], acc) do 4008 acc 4009 end 4010 4011 ## drop 4012 4013 defp drop_list(list, 0), do: list 4014 defp drop_list([_ | tail], counter), do: drop_list(tail, counter - 1) 4015 defp drop_list([], _), do: [] 4016 4017 ## drop_while 4018 4019 defp drop_while_list([head | tail], fun) do 4020 if fun.(head) do 4021 drop_while_list(tail, fun) 4022 else 4023 [head | tail] 4024 end 4025 end 4026 4027 defp drop_while_list([], _) do 4028 [] 4029 end 4030 4031 ## filter 4032 4033 defp filter_list([head | tail], fun) do 4034 if fun.(head) do 4035 [head | filter_list(tail, fun)] 4036 else 4037 filter_list(tail, fun) 4038 end 4039 end 4040 4041 defp filter_list([], _fun) do 4042 [] 4043 end 4044 4045 ## find 4046 4047 defp find_list([head | tail], default, fun) do 4048 if fun.(head) do 4049 head 4050 else 4051 find_list(tail, default, fun) 4052 end 4053 end 4054 4055 defp find_list([], default, _) do 4056 default 4057 end 4058 4059 ## find_index 4060 4061 defp find_index_list([head | tail], counter, fun) do 4062 if fun.(head) do 4063 counter 4064 else 4065 find_index_list(tail, counter + 1, fun) 4066 end 4067 end 4068 4069 defp find_index_list([], _, _) do 4070 nil 4071 end 4072 4073 ## find_value 4074 4075 defp find_value_list([head | tail], default, fun) do 4076 fun.(head) || find_value_list(tail, default, fun) 4077 end 4078 4079 defp find_value_list([], default, _) do 4080 default 4081 end 4082 4083 ## flat_map 4084 4085 defp flat_map_list([head | tail], fun) do 4086 case fun.(head) do 4087 list when is_list(list) -> list ++ flat_map_list(tail, fun) 4088 other -> to_list(other) ++ flat_map_list(tail, fun) 4089 end 4090 end 4091 4092 defp flat_map_list([], _fun) do 4093 [] 4094 end 4095 4096 ## intersperse 4097 4098 defp intersperse_non_empty_list([head], _separator), do: [head] 4099 4100 defp intersperse_non_empty_list([head | rest], separator) do 4101 [head, separator | intersperse_non_empty_list(rest, separator)] 4102 end 4103 4104 ## join 4105 4106 defp join_list([], _joiner), do: "" 4107 4108 defp join_list(list, joiner) do 4109 join_non_empty_list(list, joiner, []) 4110 |> :lists.reverse() 4111 |> IO.iodata_to_binary() 4112 end 4113 4114 defp join_non_empty_list([first], _joiner, acc), do: [entry_to_string(first) | acc] 4115 4116 defp join_non_empty_list([first | rest], joiner, acc) do 4117 join_non_empty_list(rest, joiner, [joiner, entry_to_string(first) | acc]) 4118 end 4119 4120 ## map_intersperse 4121 4122 defp map_intersperse_list([], _, _), 4123 do: [] 4124 4125 defp map_intersperse_list([last], _, mapper), 4126 do: [mapper.(last)] 4127 4128 defp map_intersperse_list([head | rest], separator, mapper), 4129 do: [mapper.(head), separator | map_intersperse_list(rest, separator, mapper)] 4130 4131 ## reduce 4132 4133 defp reduce_range(first, last, step, acc, fun) 4134 when step > 0 and first <= last 4135 when step < 0 and first >= last do 4136 reduce_range(first + step, last, step, fun.(first, acc), fun) 4137 end 4138 4139 defp reduce_range(_first, _last, _step, acc, _fun) do 4140 acc 4141 end 4142 4143 defp reduce_enumerable(enumerable, acc, fun) do 4144 Enumerable.reduce(enumerable, {:cont, acc}, fn x, acc -> {:cont, fun.(x, acc)} end) |> elem(1) 4145 end 4146 4147 ## reject 4148 4149 defp reject_list([head | tail], fun) do 4150 if fun.(head) do 4151 reject_list(tail, fun) 4152 else 4153 [head | reject_list(tail, fun)] 4154 end 4155 end 4156 4157 defp reject_list([], _fun) do 4158 [] 4159 end 4160 4161 ## reverse_slice 4162 4163 defp reverse_slice(rest, idx, idx, count, acc) do 4164 {slice, rest} = head_slice(rest, count, []) 4165 :lists.reverse(rest, :lists.reverse(slice, acc)) 4166 end 4167 4168 defp reverse_slice([elem | rest], idx, start, count, acc) do 4169 reverse_slice(rest, idx - 1, start, count, [elem | acc]) 4170 end 4171 4172 defp head_slice(rest, 0, acc), do: {acc, rest} 4173 4174 defp head_slice([elem | rest], count, acc) do 4175 head_slice(rest, count - 1, [elem | acc]) 4176 end 4177 4178 ## scan 4179 4180 defp scan_list([], _acc, _fun), do: [] 4181 4182 defp scan_list([elem | rest], acc, fun) do 4183 acc = fun.(elem, acc) 4184 [acc | scan_list(rest, acc, fun)] 4185 end 4186 4187 ## shuffle 4188 4189 defp shuffle_unwrap([{_, h} | enumerable], t) do 4190 shuffle_unwrap(enumerable, [h | t]) 4191 end 4192 4193 defp shuffle_unwrap([], t), do: t 4194 4195 ## slice 4196 4197 defp slice_any(enumerable, start, amount) when start < 0 do 4198 {count, fun} = slice_count_and_fun(enumerable) 4199 start = count + start 4200 4201 if start >= 0 do 4202 fun.(start, Kernel.min(amount, count - start)) 4203 else 4204 [] 4205 end 4206 end 4207 4208 defp slice_any(list, start, amount) when is_list(list) do 4209 list |> drop_list(start) |> take_list(amount) 4210 end 4211 4212 defp slice_any(enumerable, start, amount) do 4213 case Enumerable.slice(enumerable) do 4214 {:ok, count, _} when start >= count -> 4215 [] 4216 4217 {:ok, count, fun} when is_function(fun) -> 4218 fun.(start, Kernel.min(amount, count - start)) 4219 4220 {:error, module} -> 4221 slice_enum(enumerable, module, start, amount) 4222 end 4223 end 4224 4225 defp slice_enum(enumerable, module, start, amount) do 4226 {_, {_, _, slice}} = 4227 module.reduce(enumerable, {:cont, {start, amount, []}}, fn 4228 _entry, {start, amount, _list} when start > 0 -> 4229 {:cont, {start - 1, amount, []}} 4230 4231 entry, {start, amount, list} when amount > 1 -> 4232 {:cont, {start, amount - 1, [entry | list]}} 4233 4234 entry, {start, amount, list} -> 4235 {:halt, {start, amount, [entry | list]}} 4236 end) 4237 4238 :lists.reverse(slice) 4239 end 4240 4241 defp slice_count_and_fun(enumerable) when is_list(enumerable) do 4242 length = length(enumerable) 4243 {length, &Enumerable.List.slice(enumerable, &1, &2, length)} 4244 end 4245 4246 defp slice_count_and_fun(enumerable) do 4247 case Enumerable.slice(enumerable) do 4248 {:ok, count, fun} when is_function(fun, 2) -> 4249 {count, fun} 4250 4251 {:error, module} -> 4252 {_, {list, count}} = 4253 module.reduce(enumerable, {:cont, {[], 0}}, fn elem, {acc, count} -> 4254 {:cont, {[elem | acc], count + 1}} 4255 end) 4256 4257 {count, &Enumerable.List.slice(:lists.reverse(list), &1, &2, count)} 4258 end 4259 end 4260 4261 ## sort 4262 4263 defp sort_reducer(entry, {:split, y, x, r, rs, bool}, fun) do 4264 cond do 4265 fun.(y, entry) == bool -> 4266 {:split, entry, y, [x | r], rs, bool} 4267 4268 fun.(x, entry) == bool -> 4269 {:split, y, entry, [x | r], rs, bool} 4270 4271 r == [] -> 4272 {:split, y, x, [entry], rs, bool} 4273 4274 true -> 4275 {:pivot, y, x, r, rs, entry, bool} 4276 end 4277 end 4278 4279 defp sort_reducer(entry, {:pivot, y, x, r, rs, s, bool}, fun) do 4280 cond do 4281 fun.(y, entry) == bool -> 4282 {:pivot, entry, y, [x | r], rs, s, bool} 4283 4284 fun.(x, entry) == bool -> 4285 {:pivot, y, entry, [x | r], rs, s, bool} 4286 4287 fun.(s, entry) == bool -> 4288 {:split, entry, s, [], [[y, x | r] | rs], bool} 4289 4290 true -> 4291 {:split, s, entry, [], [[y, x | r] | rs], bool} 4292 end 4293 end 4294 4295 defp sort_reducer(entry, [x], fun) do 4296 {:split, entry, x, [], [], fun.(x, entry)} 4297 end 4298 4299 defp sort_reducer(entry, acc, _fun) do 4300 [entry | acc] 4301 end 4302 4303 defp sort_terminator({:split, y, x, r, rs, bool}, fun) do 4304 sort_merge([[y, x | r] | rs], fun, bool) 4305 end 4306 4307 defp sort_terminator({:pivot, y, x, r, rs, s, bool}, fun) do 4308 sort_merge([[s], [y, x | r] | rs], fun, bool) 4309 end 4310 4311 defp sort_terminator(acc, _fun) do 4312 acc 4313 end 4314 4315 defp sort_merge(list, fun, true), do: reverse_sort_merge(list, [], fun, true) 4316 4317 defp sort_merge(list, fun, false), do: sort_merge(list, [], fun, false) 4318 4319 defp sort_merge([t1, [h2 | t2] | l], acc, fun, true), 4320 do: sort_merge(l, [sort_merge1(t1, h2, t2, [], fun, false) | acc], fun, true) 4321 4322 defp sort_merge([[h2 | t2], t1 | l], acc, fun, false), 4323 do: sort_merge(l, [sort_merge1(t1, h2, t2, [], fun, false) | acc], fun, false) 4324 4325 defp sort_merge([l], [], _fun, _bool), do: l 4326 4327 defp sort_merge([l], acc, fun, bool), 4328 do: reverse_sort_merge([:lists.reverse(l, []) | acc], [], fun, bool) 4329 4330 defp sort_merge([], acc, fun, bool), do: reverse_sort_merge(acc, [], fun, bool) 4331 4332 defp reverse_sort_merge([[h2 | t2], t1 | l], acc, fun, true), 4333 do: reverse_sort_merge(l, [sort_merge1(t1, h2, t2, [], fun, true) | acc], fun, true) 4334 4335 defp reverse_sort_merge([t1, [h2 | t2] | l], acc, fun, false), 4336 do: reverse_sort_merge(l, [sort_merge1(t1, h2, t2, [], fun, true) | acc], fun, false) 4337 4338 defp reverse_sort_merge([l], acc, fun, bool), 4339 do: sort_merge([:lists.reverse(l, []) | acc], [], fun, bool) 4340 4341 defp reverse_sort_merge([], acc, fun, bool), do: sort_merge(acc, [], fun, bool) 4342 4343 defp sort_merge1([h1 | t1], h2, t2, m, fun, bool) do 4344 if fun.(h1, h2) == bool do 4345 sort_merge2(h1, t1, t2, [h2 | m], fun, bool) 4346 else 4347 sort_merge1(t1, h2, t2, [h1 | m], fun, bool) 4348 end 4349 end 4350 4351 defp sort_merge1([], h2, t2, m, _fun, _bool), do: :lists.reverse(t2, [h2 | m]) 4352 4353 defp sort_merge2(h1, t1, [h2 | t2], m, fun, bool) do 4354 if fun.(h1, h2) == bool do 4355 sort_merge2(h1, t1, t2, [h2 | m], fun, bool) 4356 else 4357 sort_merge1(t1, h2, t2, [h1 | m], fun, bool) 4358 end 4359 end 4360 4361 defp sort_merge2(h1, t1, [], m, _fun, _bool), do: :lists.reverse(t1, [h1 | m]) 4362 4363 ## split 4364 4365 defp split_list([head | tail], counter, acc) when counter > 0 do 4366 split_list(tail, counter - 1, [head | acc]) 4367 end 4368 4369 defp split_list(list, 0, acc) do 4370 {:lists.reverse(acc), list} 4371 end 4372 4373 defp split_list([], _, acc) do 4374 {:lists.reverse(acc), []} 4375 end 4376 4377 defp split_reverse_list([head | tail], counter, acc) when counter > 0 do 4378 split_reverse_list(tail, counter - 1, [head | acc]) 4379 end 4380 4381 defp split_reverse_list(list, 0, acc) do 4382 {:lists.reverse(list), acc} 4383 end 4384 4385 defp split_reverse_list([], _, acc) do 4386 {[], acc} 4387 end 4388 4389 ## split_while 4390 4391 defp split_while_list([head | tail], fun, acc) do 4392 if fun.(head) do 4393 split_while_list(tail, fun, [head | acc]) 4394 else 4395 {:lists.reverse(acc), [head | tail]} 4396 end 4397 end 4398 4399 defp split_while_list([], _, acc) do 4400 {:lists.reverse(acc), []} 4401 end 4402 4403 ## take 4404 4405 defp take_list([head | _], 1), do: [head] 4406 defp take_list([head | tail], counter), do: [head | take_list(tail, counter - 1)] 4407 defp take_list([], _counter), do: [] 4408 4409 ## take_while 4410 4411 defp take_while_list([head | tail], fun) do 4412 if fun.(head) do 4413 [head | take_while_list(tail, fun)] 4414 else 4415 [] 4416 end 4417 end 4418 4419 defp take_while_list([], _) do 4420 [] 4421 end 4422 4423 ## uniq 4424 4425 defp uniq_list([head | tail], set, fun) do 4426 value = fun.(head) 4427 4428 case set do 4429 %{^value => true} -> uniq_list(tail, set, fun) 4430 %{} -> [head | uniq_list(tail, Map.put(set, value, true), fun)] 4431 end 4432 end 4433 4434 defp uniq_list([], _set, _fun) do 4435 [] 4436 end 4437 4438 ## zip 4439 4440 defp zip_list([head1 | next1], [head2 | next2], acc) do 4441 zip_list(next1, next2, [{head1, head2} | acc]) 4442 end 4443 4444 defp zip_list([], _, acc), do: :lists.reverse(acc) 4445 defp zip_list(_, [], acc), do: :lists.reverse(acc) 4446 4447 defp zip_with_list([head1 | next1], [head2 | next2], fun) do 4448 [fun.(head1, head2) | zip_with_list(next1, next2, fun)] 4449 end 4450 4451 defp zip_with_list(_, [], _fun), do: [] 4452 defp zip_with_list([], _, _fun), do: [] 4453 4454 defp zip_reduce_list([head1 | next1], [head2 | next2], acc, fun) do 4455 zip_reduce_list(next1, next2, fun.(head1, head2, acc), fun) 4456 end 4457 4458 defp zip_reduce_list(_, [], acc, _fun), do: acc 4459 defp zip_reduce_list([], _, acc, _fun), do: acc 4460end 4461 4462defimpl Enumerable, for: List do 4463 def count([]), do: {:ok, 0} 4464 def count(_list), do: {:error, __MODULE__} 4465 4466 def member?([], _value), do: {:ok, false} 4467 def member?(_list, _value), do: {:error, __MODULE__} 4468 4469 def slice([]), do: {:ok, 0, fn _, _ -> [] end} 4470 def slice(_list), do: {:error, __MODULE__} 4471 4472 def reduce(_list, {:halt, acc}, _fun), do: {:halted, acc} 4473 def reduce(list, {:suspend, acc}, fun), do: {:suspended, acc, &reduce(list, &1, fun)} 4474 def reduce([], {:cont, acc}, _fun), do: {:done, acc} 4475 def reduce([head | tail], {:cont, acc}, fun), do: reduce(tail, fun.(head, acc), fun) 4476 4477 @doc false 4478 def slice(_list, _start, 0, _size), do: [] 4479 def slice(list, start, count, size) when start + count == size, do: list |> drop(start) 4480 def slice(list, start, count, _size), do: list |> drop(start) |> take(count) 4481 4482 defp drop(list, 0), do: list 4483 defp drop([_ | tail], count), do: drop(tail, count - 1) 4484 4485 defp take(_list, 0), do: [] 4486 defp take([head | tail], count), do: [head | take(tail, count - 1)] 4487end 4488 4489defimpl Enumerable, for: Map do 4490 def count(map) do 4491 {:ok, map_size(map)} 4492 end 4493 4494 def member?(map, {key, value}) do 4495 {:ok, match?(%{^key => ^value}, map)} 4496 end 4497 4498 def member?(_map, _other) do 4499 {:ok, false} 4500 end 4501 4502 def slice(map) do 4503 size = map_size(map) 4504 {:ok, size, &Enumerable.List.slice(:maps.to_list(map), &1, &2, size)} 4505 end 4506 4507 def reduce(map, acc, fun) do 4508 Enumerable.List.reduce(:maps.to_list(map), acc, fun) 4509 end 4510end 4511 4512defimpl Enumerable, for: Function do 4513 def count(_function), do: {:error, __MODULE__} 4514 def member?(_function, _value), do: {:error, __MODULE__} 4515 def slice(_function), do: {:error, __MODULE__} 4516 4517 def reduce(function, acc, fun) when is_function(function, 2), do: function.(acc, fun) 4518 4519 def reduce(function, _acc, _fun) do 4520 raise Protocol.UndefinedError, 4521 protocol: @protocol, 4522 value: function, 4523 description: "only anonymous functions of arity 2 are enumerable" 4524 end 4525end 4526