diff --git a/lists/arraylist/arraylist.go b/lists/arraylist/arraylist.go index 1ace92a..e0919eb 100644 --- a/lists/arraylist/arraylist.go +++ b/lists/arraylist/arraylist.go @@ -11,9 +11,10 @@ package arraylist import ( "fmt" + "strings" + "github.com/emirpasic/gods/lists" "github.com/emirpasic/gods/utils" - "strings" ) func assertListImplementation() { @@ -162,6 +163,22 @@ func (list *List) Insert(index int, values ...interface{}) { copy(list.elements[index:], values) } +// Set the value at specified index +// Does not do anything if position is negative or bigger than list's size +// Note: position equal to list's size is valid, i.e. append. +func (list *List) Set(index int, value interface{}) { + + if !list.withinRange(index) { + // Append + if index == list.size { + list.Add(value) + } + return + } + + list.elements[index] = value +} + // String returns a string representation of container func (list *List) String() string { str := "ArrayList\n" diff --git a/lists/arraylist/arraylist_test.go b/lists/arraylist/arraylist_test.go index 3e31e3d..c4d9a7c 100644 --- a/lists/arraylist/arraylist_test.go +++ b/lists/arraylist/arraylist_test.go @@ -178,6 +178,27 @@ func TestListInsert(t *testing.T) { } } +func TestListSet(t *testing.T) { + list := New() + list.Set(0, "a") + list.Set(1, "b") + if actualValue := list.Size(); actualValue != 2 { + t.Errorf("Got %v expected %v", actualValue, 2) + } + list.Set(2, "c") // append + if actualValue := list.Size(); actualValue != 3 { + t.Errorf("Got %v expected %v", actualValue, 3) + } + list.Set(4, "d") // ignore + list.Set(1, "bb") // update + if actualValue := list.Size(); actualValue != 3 { + t.Errorf("Got %v expected %v", actualValue, 3) + } + if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abbc"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } +} + func TestListEach(t *testing.T) { list := New() list.Add("a", "b", "c") diff --git a/lists/doublylinkedlist/doublylinkedlist.go b/lists/doublylinkedlist/doublylinkedlist.go index ab0e1bc..836d867 100644 --- a/lists/doublylinkedlist/doublylinkedlist.go +++ b/lists/doublylinkedlist/doublylinkedlist.go @@ -11,9 +11,10 @@ package doublylinkedlist import ( "fmt" + "strings" + "github.com/emirpasic/gods/lists" "github.com/emirpasic/gods/utils" - "strings" ) func assertListImplementation() { @@ -292,6 +293,37 @@ func (list *List) Insert(index int, values ...interface{}) { } } +// Sets value at specified index position +// Does not do anything if position is negative or bigger than list's size +// Note: position equal to list's size is valid, i.e. append. +func (list *List) Set(index int, value interface{}) { + + if !list.withinRange(index) { + // Append + if index == list.size { + list.Add(value) + } + return + } + + var foundElement *element + // determine traversal direction, last to first or first to last + if list.size-index < index { + foundElement = list.last + for e := list.size - 1; e != index; { + fmt.Println("Set last", index, value, foundElement, foundElement.prev) + e, foundElement = e-1, foundElement.prev + } + } else { + foundElement = list.first + for e := 0; e != index; { + e, foundElement = e+1, foundElement.next + } + } + + foundElement.value = value +} + // String returns a string representation of container func (list *List) String() string { str := "DoublyLinkedList\n" diff --git a/lists/doublylinkedlist/doublylinkedlist_test.go b/lists/doublylinkedlist/doublylinkedlist_test.go index 4794da9..1f0d5a6 100644 --- a/lists/doublylinkedlist/doublylinkedlist_test.go +++ b/lists/doublylinkedlist/doublylinkedlist_test.go @@ -6,8 +6,9 @@ package doublylinkedlist import ( "fmt" - "github.com/emirpasic/gods/utils" "testing" + + "github.com/emirpasic/gods/utils" ) func TestListAdd(t *testing.T) { @@ -177,6 +178,32 @@ func TestListInsert(t *testing.T) { } } +func TestListSet(t *testing.T) { + list := New() + list.Set(0, "a") + list.Set(1, "b") + if actualValue := list.Size(); actualValue != 2 { + t.Errorf("Got %v expected %v", actualValue, 2) + } + list.Set(2, "c") // append + if actualValue := list.Size(); actualValue != 3 { + t.Errorf("Got %v expected %v", actualValue, 3) + } + list.Set(4, "d") // ignore + list.Set(1, "bb") // update + if actualValue := list.Size(); actualValue != 3 { + t.Errorf("Got %v expected %v", actualValue, 3) + } + if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abbc"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } + list.Set(2, "cc") // last to first traversal + list.Set(0, "aa") // first to last traversal + if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "aabbcc"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } +} + func TestListEach(t *testing.T) { list := New() list.Add("a", "b", "c") diff --git a/lists/lists.go b/lists/lists.go index 3b1d323..1f6bb08 100644 --- a/lists/lists.go +++ b/lists/lists.go @@ -23,6 +23,7 @@ type List interface { Sort(comparator utils.Comparator) Swap(index1, index2 int) Insert(index int, values ...interface{}) + Set(index int, value interface{}) containers.Container // Empty() bool diff --git a/lists/singlylinkedlist/singlylinkedlist.go b/lists/singlylinkedlist/singlylinkedlist.go index 45ee69c..2d0f0bb 100644 --- a/lists/singlylinkedlist/singlylinkedlist.go +++ b/lists/singlylinkedlist/singlylinkedlist.go @@ -11,9 +11,10 @@ package singlylinkedlist import ( "fmt" + "strings" + "github.com/emirpasic/gods/lists" "github.com/emirpasic/gods/utils" - "strings" ) func assertListImplementation() { @@ -260,6 +261,26 @@ func (list *List) Insert(index int, values ...interface{}) { } } +// Sets value at specified index +// Does not do anything if position is negative or bigger than list's size +// Note: position equal to list's size is valid, i.e. append. +func (list *List) Set(index int, value interface{}) { + + if !list.withinRange(index) { + // Append + if index == list.size { + list.Add(value) + } + return + } + + foundElement := list.first + for e := 0; e != index; { + e, foundElement = e+1, foundElement.next + } + foundElement.value = value +} + // String returns a string representation of container func (list *List) String() string { str := "SinglyLinkedList\n" diff --git a/lists/singlylinkedlist/singlylinkedlist_test.go b/lists/singlylinkedlist/singlylinkedlist_test.go index 36e080d..de1cd0d 100644 --- a/lists/singlylinkedlist/singlylinkedlist_test.go +++ b/lists/singlylinkedlist/singlylinkedlist_test.go @@ -6,8 +6,9 @@ package singlylinkedlist import ( "fmt" - "github.com/emirpasic/gods/utils" "testing" + + "github.com/emirpasic/gods/utils" ) func TestListAdd(t *testing.T) { @@ -177,6 +178,27 @@ func TestListInsert(t *testing.T) { } } +func TestListSet(t *testing.T) { + list := New() + list.Set(0, "a") + list.Set(1, "b") + if actualValue := list.Size(); actualValue != 2 { + t.Errorf("Got %v expected %v", actualValue, 2) + } + list.Set(2, "c") // append + if actualValue := list.Size(); actualValue != 3 { + t.Errorf("Got %v expected %v", actualValue, 3) + } + list.Set(4, "d") // ignore + list.Set(1, "bb") // update + if actualValue := list.Size(); actualValue != 3 { + t.Errorf("Got %v expected %v", actualValue, 3) + } + if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abbc"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } +} + func TestListEach(t *testing.T) { list := New() list.Add("a", "b", "c")