絞り込み検索部分を改正してみました

Mar 23, 2009 at 2:52 PM

    '// Original codes //
    'Private Function FilterProgram(ByVal sender As Object) As Boolean
    '    Dim program = DirectCast(sender, LiveProgram)

    '    Dim words = FilterTextBox.Text.ToLower.Split(New Char() {" "c, " "c}, StringSplitOptions.RemoveEmptyEntries)
    '    If words.Length = 0 Then
    '        Return True
    '    End If

    '    For Each w In words
    '        If program.Title.ToLower.Contains(w) OrElse _
    '           program.Station.Name.ToLower.Contains(w) OrElse _
    '           program.Content.ToLower.Contains(w) OrElse _
    '           program.Caster.ToLower.Contains(w) Then
    '            Continue For
    '        Else
    '            Return False
    '        End If
    '    Next
    '    Return True

    'End Function

    '// Modification codes by mu-lp. 2009-03-23. //
    Private Enum KeyWordType
        AndKW
        OrKW
        NotKW
    End Enum

    Private Function FilterProgram(ByVal sender As Object) As Boolean
        Dim program = DirectCast(sender, LiveProgram)
        'ローカル変数宣言
        Dim andWords As New ArrayList   '連言
        Dim orWords As New ArrayList    '選言
        Dim notWords As New ArrayList   '否定
        Dim FilterWords As String
        Dim Word As String
        Dim Type As KeyWordType

        FilterWords = CStr(FilterTextBox.Text.ToLower.Clone) + " " '末尾にスペースを足すのは「とある」おまじない
        Word = ""
        Type = KeyWordType.AndKW
        'トークン分解 ループ
        For Each c In FilterWords
            If c = " "c Or c = " "c Or c = "&"c Or c = "|"c Or c = "~"c Then
                If Word.Length > 0 Then
                    Select Case Type
                        Case KeyWordType.AndKW
                            andWords.Add(Word.Clone)
                        Case KeyWordType.OrKW
                            orWords.Add(Word.Clone)
                        Case KeyWordType.NotKW
                            notWords.Add(Word.Clone)
                    End Select
                End If
                Word = ""
            End If
            If c = " "c Or c = " "c Or c = "&"c Then
                Type = KeyWordType.AndKW
            ElseIf c = "|"c Then
                Type = KeyWordType.OrKW
            ElseIf c = "~"c Then
                Type = KeyWordType.NotKW
            Else
                Word += c
            End If
        Next
        '絞り込みワードが0個ならtrue返して関数終了
        If andWords.Count = 0 And _
           orWords.Count = 0 And _
           notWords.Count = 0 Then
            Return True
        End If
        'NOTキーワードが含まれているか判別
        For Each notw In notWords
            Word = CStr(notw)
            If program.Title.ToLower.Contains(Word) OrElse _
               program.Station.Name.ToLower.Contains(Word) OrElse _
               program.Content.ToLower.Contains(Word) OrElse _
               program.Caster.ToLower.Contains(Word) Then
                Return False    'NOTキーワードが1個でも含まれていたらfalseを返して関数終了
            End If
        Next
        'ORキーワードが含まれているか判別
        For Each orw In orWords
            Word = CStr(orw)
            If program.Title.ToLower.Contains(Word) OrElse _
               program.Station.Name.ToLower.Contains(Word) OrElse _
               program.Content.ToLower.Contains(Word) OrElse _
               program.Caster.ToLower.Contains(Word) Then
                GoTo SKIP_ANDKEYWORD_MATCH   'ORキーワードが1個でも含まれていた場合、ANDキーワードマッチングをスキップ
            End If
        Next
        'ANDキーワード全て含まれているか判別
        If andWords.Count > 0 Then
            For Each andw In andWords
                Word = CStr(andw)
                If program.Title.ToLower.Contains(Word) OrElse _
                   program.Station.Name.ToLower.Contains(Word) OrElse _
                   program.Content.ToLower.Contains(Word) OrElse _
                   program.Caster.ToLower.Contains(Word) Then
                    Continue For
                Else
                    Return False    'ANDキーワードが含まれて無いなら、falseを返して関数終了
                End If
            Next
        Else
            Return False    'ANDキーワードが0個なら、falseを返して関数終了
        End If
SKIP_ANDKEYWORD_MATCH:

        '此所まで処理が来た場合、絞り込みキーワード条件にマッチした事を意味する。
        Return True
    End Function

Coordinator
Mar 23, 2009 at 3:36 PM
書き変えて組み込んでみました。

Dim program = DirectCast(sender, LiveProgram)

Dim andWords = New List(Of String)
Dim orWords = New List(Of String)
Dim notWords = New List(Of String)
Dim targetList As IList(Of String) = andWords

Dim filterText = FilterTextBox.Text.ToLower & " " '末尾にスペースを足すのは「とある」おまじない
Dim word As String = ""

' トークン分解 ループ
For Each c In filterText
    If "  &|-".Contains(c) AndAlso word.Length > 0 Then
        targetList.Add(word)
        word = ""
    End If

    Select Case c
        Case " "c, " "c, "&"c
            targetList = andWords
        Case "|"c
            targetList = orWords
        Case "-"c
            targetList = notWords
        Case Else
            word &= c
    End Select
Next

' 絞り込みワードが0個ならtrue返して関数終了
If andWords.Count = 0 AndAlso orWords.Count = 0 AndAlso notWords.Count = 0 Then
    Return True
End If

' NOTキーワードが含まれているか判別
For Each w In notWords
    If program.Title.ToLower.Contains(w) OrElse _
       program.Station.Name.ToLower.Contains(w) OrElse _
       program.Content.ToLower.Contains(w) OrElse _
       If(program.Caster, "").ToLower.Contains(w) Then

        Return False
    End If
Next

' ORキーワードが含まれているか判別
For Each w In orWords
    If program.Title.ToLower.Contains(w) OrElse _
       program.Station.Name.ToLower.Contains(w) OrElse _
       program.Content.ToLower.Contains(w) OrElse _
       If(program.Caster, "").ToLower.Contains(w) Then
        Return True
    End If
Next

' ANDキーワード全て含まれているか判別
If andWords.Count = 0 Then
    Return False
End If

For Each w In andWords
    If program.Title.ToLower.Contains(w) OrElse _
       program.Station.Name.ToLower.Contains(w) OrElse _
       program.Content.ToLower.Contains(w) OrElse _
      If(program.Caster, "").ToLower.Contains(w) Then
        Continue For
    Else
        Return False
    End If
Next

Return True