From 325be0d6a1b49f6bc6c47a2f72a34b552a5ab8ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=87=95=E5=BD=92=E6=9D=A5?= Date: Mon, 6 Feb 2023 09:46:25 +0800 Subject: [PATCH] feat: add func Iterator, ForEach, RetainAll and DeleteAll for List structure (#71) --- datastructure/list/list.go | 44 +++++++++++++++++++++ datastructure/list/list_test.go | 68 +++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/datastructure/list/list.go b/datastructure/list/list.go index 31687bd..ef77b0f 100644 --- a/datastructure/list/list.go +++ b/datastructure/list/list.go @@ -5,6 +5,7 @@ package datastructure import ( + "github.com/duke-git/lancet/v2/iterator" "reflect" ) @@ -323,3 +324,46 @@ func (l *List[T]) SubList(fromIndex, toIndex int) *List[T] { copy(subList, data) return NewList(subList) } + +// ForEach performs the given action for each element of the list. +func (l *List[T]) ForEach(consumer func(T)) { + for _, it := range l.data { + consumer(it) + } +} + +// RetainAll retains only the elements in this list that are contained in the given list. +func (l *List[T]) RetainAll(list *List[T]) bool { + return l.batchRemove(list, true) +} + +// DeleteAll removes from this list all of its elements that are contained in the given list. +func (l *List[T]) DeleteAll(list *List[T]) bool { + return l.batchRemove(list, false) +} + +func (l *List[T]) batchRemove(list *List[T], complement bool) bool { + var ( + w = 0 + data = l.data + size = len(data) + ) + + for i := 0; i < size; i++ { + if list.Contain(data[i]) == complement { + data[w] = data[i] + w++ + } + } + + if w != size { + l.data = data[:w] + return true + } + return false +} + +// Iterator returns an iterator over the elements in this list in proper sequence. +func (l *List[T]) Iterator() iterator.Iterator[T] { + return iterator.FromSlice(l.data) +} diff --git a/datastructure/list/list_test.go b/datastructure/list/list_test.go index 33a5c27..0ce58ba 100644 --- a/datastructure/list/list_test.go +++ b/datastructure/list/list_test.go @@ -357,3 +357,71 @@ func TestDeleteIf(t *testing.T) { assert.Equal([]int{2, 3, 4}, list.Data()) assert.Equal(0, count) } + +func TestForEach(t *testing.T) { + assert := internal.NewAssert(t, "TestForEach") + + list := NewList([]int{1, 2, 3, 4}) + + rs := make([]int, 0) + list.ForEach(func(i int) { + rs = append(rs, i) + }) + + assert.Equal([]int{1, 2, 3, 4}, rs) +} + +func TestRetainAll(t *testing.T) { + assert := internal.NewAssert(t, "TestRetainAll") + + list := NewList([]int{1, 2, 3, 4}) + list1 := NewList([]int{1, 2, 3, 4}) + list2 := NewList([]int{1, 2, 3, 4}) + + retain := NewList([]int{1, 2}) + retain1 := NewList([]int{2, 3}) + retain2 := NewList([]int{1, 2, 5}) + + list.RetainAll(retain) + list1.RetainAll(retain1) + list2.RetainAll(retain2) + + assert.Equal([]int{1, 2}, list.Data()) + assert.Equal([]int{2, 3}, list1.Data()) + assert.Equal([]int{1, 2}, list2.Data()) +} + +func TestDeleteAll(t *testing.T) { + assert := internal.NewAssert(t, "TestDeleteAll") + + list := NewList([]int{1, 2, 3, 4}) + list1 := NewList([]int{1, 2, 3, 4}) + list2 := NewList([]int{1, 2, 3, 4}) + + del := NewList([]int{1}) + del1 := NewList([]int{2, 3}) + del2 := NewList([]int{1, 2, 5}) + + list.DeleteAll(del) + list1.DeleteAll(del1) + list2.DeleteAll(del2) + assert.Equal([]int{2, 3, 4}, list.Data()) + assert.Equal([]int{1, 4}, list1.Data()) + assert.Equal([]int{3, 4}, list2.Data()) +} + +func TestIterator(t *testing.T) { + assert := internal.NewAssert(t, "TestIterator") + + list := NewList([]int{1, 2, 3, 4}) + + iterator := list.Iterator() + + rs := make([]int, 0) + for iterator.HasNext() { + item, _ := iterator.Next() + rs = append(rs, item) + } + + assert.Equal([]int{1, 2, 3, 4}, rs) +}