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 1/2] 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) +} From 17e8d2bb6d351416095c993616adcdcd3b3731ea Mon Sep 17 00:00:00 2001 From: Cai Zhijiang Date: Mon, 6 Feb 2023 09:47:21 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E9=83=A8=E5=88=86=E5=9F=8E=E5=B8=82?= =?UTF-8?q?=E6=9C=894=E4=BD=8D=E5=8C=BA=E5=8F=B7+8=E4=BD=8D=E5=8F=B7?= =?UTF-8?q?=E7=A0=81=20(#69)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- validator/validator.go | 2 +- validator/validator_test.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/validator/validator.go b/validator/validator.go index e1dbb50..2127571 100644 --- a/validator/validator.go +++ b/validator/validator.go @@ -25,7 +25,7 @@ var ( chineseMobileMatcher *regexp.Regexp = regexp.MustCompile(`^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$`) chineseIdMatcher *regexp.Regexp = regexp.MustCompile(`^[1-9]\d{5}(18|19|20|21|22)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$`) chineseMatcher *regexp.Regexp = regexp.MustCompile("[\u4e00-\u9fa5]") - chinesePhoneMatcher *regexp.Regexp = regexp.MustCompile(`\d{3}-\d{8}|\d{4}-\d{7}`) + chinesePhoneMatcher *regexp.Regexp = regexp.MustCompile(`\d{3}-\d{8}|\d{4}-\d{7}|\d{4}-\d{8}`) creditCardMatcher *regexp.Regexp = regexp.MustCompile(`^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11}|6[27][0-9]{14})$`) base64Matcher *regexp.Regexp = regexp.MustCompile(`^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$`) ) diff --git a/validator/validator_test.go b/validator/validator_test.go index 6a237a5..34ba876 100644 --- a/validator/validator_test.go +++ b/validator/validator_test.go @@ -208,6 +208,7 @@ func TestIsChinesePhone(t *testing.T) { assert.Equal(true, IsChinesePhone("010-32116675")) assert.Equal(true, IsChinesePhone("0464-8756213")) + assert.Equal(true, IsChinesePhone("0731-82251545")) //长沙晚报电话 assert.Equal(false, IsChinesePhone("123-87562")) }