Ver código fonte

support customized mask char on trie

kevin 4 anos atrás
pai
commit
2ebb5b6b58
2 arquivos alterados com 26 adições e 8 exclusões
  1. 20 2
      core/stringx/trie.go
  2. 6 6
      core/stringx/trie_test.go

+ 20 - 2
core/stringx/trie.go

@@ -2,7 +2,11 @@ package stringx
 
 import "github.com/tal-tech/go-zero/core/lang"
 
+const defaultMask = '*'
+
 type (
+	TrieOption func(trie *trieNode)
+
 	Trie interface {
 		Filter(text string) (string, []string, bool)
 		FindKeywords(text string) []string
@@ -10,6 +14,7 @@ type (
 
 	trieNode struct {
 		node
+		mask rune
 	}
 
 	scope struct {
@@ -18,8 +23,15 @@ type (
 	}
 )
 
-func NewTrie(words []string) Trie {
+func NewTrie(words []string, opts ...TrieOption) Trie {
 	n := new(trieNode)
+
+	for _, opt := range opts {
+		opt(n)
+	}
+	if n.mask == 0 {
+		n.mask = defaultMask
+	}
 	for _, word := range words {
 		n.add(word)
 	}
@@ -114,6 +126,12 @@ func (n *trieNode) findKeywordScopes(chars []rune) []scope {
 
 func (n *trieNode) replaceWithAsterisk(chars []rune, start, stop int) {
 	for i := start; i < stop; i++ {
-		chars[i] = '*'
+		chars[i] = n.mask
+	}
+}
+
+func WithMask(mask rune) TrieOption {
+	return func(n *trieNode) {
+		n.mask = mask
 	}
 }

+ 6 - 6
core/stringx/trie_test.go

@@ -109,25 +109,25 @@ func TestTrie(t *testing.T) {
 func TestTrieSingleWord(t *testing.T) {
 	trie := NewTrie([]string{
 		"闹",
-	})
+	}, WithMask('#'))
 	output, keywords, ok := trie.Filter("今晚真热闹")
 	assert.ElementsMatch(t, []string{"闹"}, keywords)
 	assert.True(t, ok)
-	assert.Equal(t, "今晚真热*", output)
+	assert.Equal(t, "今晚真热#", output)
 }
 
 func TestTrieOverlap(t *testing.T) {
 	trie := NewTrie([]string{
 		"一二三四五",
 		"二三四五六七八",
-	})
+	}, WithMask('#'))
 	output, keywords, ok := trie.Filter("零一二三四五六七八九十")
 	assert.ElementsMatch(t, []string{
 		"一二三四五",
 		"二三四五六七八",
 	}, keywords)
 	assert.True(t, ok)
-	assert.Equal(t, "零********九十", output)
+	assert.Equal(t, "零########九十", output)
 }
 
 func TestTrieNested(t *testing.T) {
@@ -135,7 +135,7 @@ func TestTrieNested(t *testing.T) {
 		"一二三",
 		"一二三四五",
 		"一二三四五六七八",
-	})
+	}, WithMask('#'))
 	output, keywords, ok := trie.Filter("零一二三四五六七八九十")
 	assert.ElementsMatch(t, []string{
 		"一二三",
@@ -143,7 +143,7 @@ func TestTrieNested(t *testing.T) {
 		"一二三四五六七八",
 	}, keywords)
 	assert.True(t, ok)
-	assert.Equal(t, "零********九十", output)
+	assert.Equal(t, "零########九十", output)
 }
 
 func BenchmarkTrie(b *testing.B) {