Skip to content

Commit 7b22b8e

Browse files
authored
Add List.first!/1 and List.last!/1 (#15082)
1 parent ba86beb commit 7b22b8e

File tree

2 files changed

+85
-2
lines changed

2 files changed

+85
-2
lines changed

lib/elixir/lib/list.ex

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,33 @@ defmodule List do
298298
def first([], default), do: default
299299
def first([head | _], _default), do: head
300300

301+
@doc """
302+
Returns the first element in `list`.
303+
304+
If `list` is empty, an error is raised.
305+
306+
## Examples
307+
308+
iex> List.first!([1])
309+
1
310+
311+
iex> List.first!([1, 2, 3])
312+
1
313+
314+
iex> List.first!([])
315+
** (ArgumentError) attempted to get the first element of an empty list
316+
317+
"""
318+
@doc since: "1.20.0"
319+
@spec first!([elem, ...]) :: elem when elem: var
320+
def first!(list)
321+
322+
def first!([head | _]), do: head
323+
324+
def first!([]) do
325+
raise ArgumentError, "attempted to get the first element of an empty list"
326+
end
327+
301328
@doc """
302329
Returns the last element in `list` or `default` if `list` is empty.
303330
@@ -326,6 +353,34 @@ defmodule List do
326353
def last([head], _default), do: head
327354
def last([_ | tail], default), do: last(tail, default)
328355

356+
@doc """
357+
Returns the last element in `list`.
358+
359+
If `list` is empty, an error is raised.
360+
361+
## Examples
362+
363+
iex> List.last!([1])
364+
1
365+
366+
iex> List.last!([1, 2, 3])
367+
3
368+
369+
iex> List.last!([])
370+
** (ArgumentError) attempted to get the last element of an empty list
371+
372+
"""
373+
@doc since: "1.20.0"
374+
@spec last!([elem, ...]) :: elem when elem: var
375+
def last!(list)
376+
377+
def last!([head]), do: head
378+
def last!([_ | tail]), do: last!(tail)
379+
380+
def last!([]) do
381+
raise ArgumentError, "attempted to get the last element of an empty list"
382+
end
383+
329384
@doc """
330385
Receives a list of tuples and returns the first tuple
331386
where the element at `position` in the tuple matches the

lib/elixir/test/elixir/list_test.exs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,46 @@ defmodule ListTest do
7676

7777
test "first/1" do
7878
assert List.first([]) == nil
79-
assert List.first([], 1) == 1
8079
assert List.first([1]) == 1
8180
assert List.first([1, 2, 3]) == 1
8281
end
8382

83+
test "first/2" do
84+
assert List.first([], 1) == 1
85+
assert List.first([2], 1) == 2
86+
assert List.first([1, 2, 3], 1) == 1
87+
end
88+
89+
test "first!/1" do
90+
assert List.first!([1]) == 1
91+
assert List.first!([1, 2, 3]) == 1
92+
93+
assert_raise ArgumentError, "attempted to get the first element of an empty list", fn ->
94+
List.first!([])
95+
end
96+
end
97+
8498
test "last/1" do
8599
assert List.last([]) == nil
86-
assert List.last([], 1) == 1
87100
assert List.last([1]) == 1
88101
assert List.last([1, 2, 3]) == 3
89102
end
90103

104+
test "last/2" do
105+
assert List.last([], 1) == 1
106+
assert List.last([2], 1) == 2
107+
assert List.last([1, 2, 3], 1) == 3
108+
end
109+
110+
test "last!/1" do
111+
assert List.last!([1]) == 1
112+
assert List.last!([1, 2, 3]) == 3
113+
114+
assert_raise ArgumentError, "attempted to get the last element of an empty list", fn ->
115+
List.last!([])
116+
end
117+
end
118+
91119
test "keyfind/4" do
92120
assert List.keyfind([a: 1, b: 2], :a, 0) == {:a, 1}
93121
assert List.keyfind([a: 1, b: 2], 2, 1) == {:b, 2}

0 commit comments

Comments
 (0)