dorking around

master
Jordan Orelli 3 years ago
parent 82696bb29a
commit ca6074e953

@ -34,7 +34,7 @@ func (l List[T]) String() string {
func Make[T any](vals ...T) List[T] { func Make[T any](vals ...T) List[T] {
var l List[T] var l List[T]
for i := len(vals)-1; i >= 0; i-- { for i := len(vals)-1; i >= 0; i-- {
l.Prepend(vals[i]) l.Push(vals[i])
} }
return l return l
} }
@ -44,14 +44,24 @@ func (l List[T]) Empty() bool {
return l.head == nil return l.head == nil
} }
// Head returns the first element of the list. If the list is empty, Head // At treats the list like an array and gets the value at the i'th position in
// returns the zero-value for the type T. This is the same thing as Peek() // the list (zero-indexed)
func (l List[T]) Head() T { func (l List[T]) At(i int) T {
if l.head == nil { for n, at := l.head, 0; n != nil; n, at = n.next, at+1 {
if at == i {
return n.val
}
}
var v T var v T
return v return v
}
// Push adds an element to the front of the list
func (l *List[T]) Push(v T) {
l.head = &node[T]{
val: v,
next: l.head,
} }
return l.head.val
} }
// Pop returns the first element of the list and removes it from the list. // Pop returns the first element of the list and removes it from the list.
@ -66,6 +76,16 @@ func (l *List[T]) Pop() T {
return v return v
} }
// Head returns the first element of the list. If the list is empty, Head
// returns the zero-value for the type T. This is the same thing as Peek()
func (l List[T]) Head() T {
if l.head == nil {
var v T
return v
}
return l.head.val
}
// Tail returns a list which is the original list without its Head element. // Tail returns a list which is the original list without its Head element.
// If the original list is an empty list or a list of size 1, Tail is an // If the original list is an empty list or a list of size 1, Tail is an
// empty list. // empty list.
@ -89,24 +109,14 @@ func (l List[T]) Len() int {
return i return i
} }
// Prepend adds an element to the front of the list
func (l *List[T]) Prepend(v T) {
l.head = &node[T]{
val: v,
next: l.head,
}
}
// Map applies the input function f to each element of the list l, returning a // Map applies the input function f to each element of the list l, returning a
// new list containing the values produced by f // new list containing the values produced by f
func (l List[T]) Map(f func(T) T) List[T] { func (l List[T]) Map(f func(T) T) List[T] {
var mapped List[T]
if l.Empty() { if l.Empty() {
return mapped return List[T]{}
} }
mapped.head = &node[T]{val: f(l.head.val)} mapped := List[T]{head: &node[T]{val: f(l.head.val)}}
last := mapped.head last := mapped.head
for n := l.head.next; n != nil; n = n.next { for n := l.head.next; n != nil; n = n.next {
last.next = &node[T]{val: f(n.val)} last.next = &node[T]{val: f(n.val)}
@ -115,3 +125,30 @@ func (l List[T]) Map(f func(T) T) List[T] {
return mapped return mapped
} }
// Filter applies a predicate function f to each element of the list and
// returns a new list containing the values of the elements that passed the
// predicate
func (l List[T]) Filter(f func(T) bool) List[T] {
if l.Empty() {
return List[T]{}
}
var passed List[T]
var last *node[T]
for n := l.head; n != nil; n = n.next {
if !f(n.val) {
continue
}
if passed.Empty() {
passed.head = &node[T]{val: n.val}
last = passed.head
} else {
last.next = &node[T]{val: n.val}
last = last.next
}
}
return passed
}

@ -28,7 +28,7 @@ func TestEmpty(t *testing.T) {
func TestOne(t *testing.T) { func TestOne(t *testing.T) {
var l List[int] var l List[int]
l.Prepend(3) l.Push(3)
if l.Empty() { if l.Empty() {
t.Errorf("list should have 1 element but is empty") t.Errorf("list should have 1 element but is empty")
@ -68,7 +68,7 @@ func TestMake(t *testing.T) {
t.Errorf("expected a head element of %q but saw %q instead", "bob", l.Head()) t.Errorf("expected a head element of %q but saw %q instead", "bob", l.Head())
} }
l.Prepend("alice") l.Push("alice")
if l.Head() != "alice" { if l.Head() != "alice" {
t.Errorf("expected a head element of %q but saw %q instead", "alice", l.Head()) t.Errorf("expected a head element of %q but saw %q instead", "alice", l.Head())
} }
@ -105,7 +105,8 @@ func eq[T comparable](t *testing.T, expect T, found T) {
func TestMap(t *testing.T) { func TestMap(t *testing.T) {
nums := Make(2, 4, 6).Map(mult(5)) nums := Make(2, 4, 6).Map(mult(5))
eq(t, 10, nums.Pop()) eq(t, 10, nums.At(0))
eq(t, 20, nums.Pop()) eq(t, 20, nums.At(1))
eq(t, 30, nums.Pop()) eq(t, 30, nums.At(2))
eq(t, 0, nums.At(3))
} }

Loading…
Cancel
Save