2012年7月24日 星期二

LINQ TO Object 關於字串查詢的幾個範例

LINQ TO Objcect ,字串string 這個類別是實作了泛型的 IEnumerable<(Of <(T>)>)介面,所以也可以用LINQ來做逐個「字符」的查詢…

◎以上程式範例LINQ3.aspx,如在頁框下不能操作,請開新視窗操作

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        ' 這邊硬式編碼(hard-coded)了要搜尋的來源,正常來說查詢的資料可能是資料庫之類的
        Me.Label1.Text = "Historically, the world of data and the world of objects" &
                         "  have not been well integrated. Programmers work in C# or Visual Basic" &
                         "  and also in SQL or XQuery! On the one side are concepts such as classes," &
                         "  objects, fields, inheritance, and .NET Framework APIs. On the other side" &
                         "  are tables, columns, rows, nodes, and separate languages for dealing with" &
                         "  them. Data types often require translation between the two worlds; there are" &
                         "  different standard functions. Because the object world has no notion of query, a" &
                         "  query can only be represented as a string without compile-time type checking or" &
                         "  IntelliSense support in the IDE. Transferring data from SQL tables or XML trees to" &
                         "  objects in memory is often tedious and error-prone.Do you understand what I say?" &
                         "  ABCDE99F-J74-12-89A"

        Me.QLabel1.Text = ""
        Me.Qlabel2.Text = ""
        Me.Button1.Text = "統計某個字在字串中出現的次數(查詢英文文章中符合搜尋條件的單字)"
        Me.Button2.Text = "查詢包含指定一組字的句子(查詢英文文章中符合搜尋條件的句子)"
        Me.Button3.Text = "查詢字串中的字元(比對是否為數字、當讀到特定字停止序列)"
        
    End Sub
    Protected Sub Button1_Click(sender As Object, e As System.EventArgs) Handles Button1.Click
        ' DEMO:統計某個字在字串中出現的次數
        ' 參考範例:http://msdn.microsoft.com/zh-tw/library/bb546166.aspx

        ' 設定要搜尋來源是 Label1.text
        Dim Qsource = Me.Label1.Text
        ' 設定要搜尋的條件:使用者輸入到 TextBox1 的文字,然後單字都小寫
        Dim QMatch = Me.TextBox1.Text.ToLowerInvariant

        ' 底下用split方法,把每個單字用分割的方式來傳回字串陣列,英語來說蠻合理的。但如果要的結果只是傳回搜尋到的次數,不需要字串陣列的話,可以用Matches 或 IndexOf 方法,效能會更好。
        ' 也因為是陣列array型式,是IEnumberable ,所以可以用LINQ查詢
        ' StringSplitOptions.RemoveEmptyEntries是再把分割出來的字再拿掉多餘的空格數。
        Dim Qcollection = Qsource.Split(New Char() {" ", ",", ".", ";", ":", "?", "!"}, StringSplitOptions.RemoveEmptyEntries)

        ' 不分大小寫的搜尋,就把來源和搜尋字統一都轉成小寫ToLower…這邊用了ToLowerInvariant,是表示不含文化產生的字母。
        Dim Qquery = From Qelement In Qcollection
                    Where Qelement.ToLowerInvariant = QMatch
                    Select Qelement
        For Each Qelement In Qquery
            Me.QLabel1.Text &= Qelement & ","
            Me.Label1.Text = Me.Label1.Text.Replace(Qelement, "<font color='#ff0000'>" & Qelement & "</font>")
        Next
        Me.Qlabel2.Text = "共查詢到 " & Qquery.Count & " 筆資料"
    End Sub
    Protected Sub Button2_Click(sender As Object, e As System.EventArgs) Handles Button2.Click
        ' DEMO:查詢包含指定一組字的句子
        ' 參考:http://msdn.microsoft.com/zh-tw/library/bb546163.aspx

        Dim Qsource = Me.Label1.Text
        Dim QMatch = Me.TextBox1.Text.Split(New Char() {" ", ",", ".", ";", ":", "?", "!"}, StringSplitOptions.RemoveEmptyEntries)

        ' 查詢的方式是先分割文章,將每個句子序列
        Dim Qcollection = Qsource.Split(New Char() {".", "?", "!"})

        ' 再將每組句子分別割開成單字,形成單字陣列
        ' 所以不是在在編譯時指定的條件相匹配的數量
        ' 而是用迴圈的方式,以每個句子為單位,查詢每個句子裡的單字是否匹配
        ' 使用了Distinct 方法移除所有重複的字,以及Intersect方法比對交集
        Dim Qquery = From Qelement In Qcollection
                    Let wordsplit = Qelement.Split(New Char() {" ", ",", ".", ";", ":"}, StringSplitOptions.RemoveEmptyEntries)
                    Where wordsplit.Distinct().Intersect(QMatch).Count = QMatch.Count
                    Select Qelement
        For Each Qelement In Qquery
            Me.QLabel1.Text &= Qelement & "</br>"
            Me.Label1.Text = Me.Label1.Text.Replace(Qelement, "<font color='#ff0000'>" & Qelement & "</font>")
        Next
        Me.Qlabel2.Text = "共查詢到 " & Qquery.Count & " 筆資料"
    End Sub

    Protected Sub Button3_Click(sender As Object, e As System.EventArgs) Handles Button3.Click
        ' DEMO:查詢字串中的字元
        ' 參考:http://msdn.microsoft.com/zh-tw/library/bb397940.aspx

        Dim Qsource = Me.Label1.Text
        Dim Qcollection = Qsource
        Dim Qquery = From Qelement In Qcollection
                     Where Char.IsDigit(Qelement) = True
                     Select Qelement
        For Each Qelement In Qquery
            QLabel1.Text &= Qelement & "、"
        Next

        ' 這個demo的重點在
        ' LINQ中查詢在第一次執行之後就會「重複使用」。 因為查詢本身並不會實際儲存任何結果,所以這是允許的。
        ' string 這個class 實作了泛型的 IEnumerable<(Of <(T>)>)介面,所以是也是一種序列,所以當然可以用linq
        ' 底下使用TakeWhile方法,只要Function(c) c <> "-" 條件是true就會一直傳回序列的項目,到了字串"-"
        ' 的時候return值是false,就停止傳回。
        ' 實際應用上,如果要進行複雜的字串比對,可以使用Regex 類別。
        Dim Qquery2 = Qcollection.TakeWhile(Function(c) c <> "-")
        For Each Qelement In Qquery2
            Qlabel2.Text &= Qelement
        Next
    End Sub

應用面大概就是針對使用者輸入的內容做比對查詢…目前還沒想到怎麼實際運用


It’s my life live love …

7月初和家人一同出遊,去了恐龍展

來去恐龍展囉!!!
來去恐龍展囉!!!

妹妹:「恐龍展是什麼?」
妹妹:「恐龍展是什麼?」

恐龍展就是…一家子難得的出遊…
恐龍展就是…一家子難得的出遊…

比起恐龍展,個人還是比較喜歡坐在魚池旁,悠然自得的餵餵魚、餵餵鴿子
比起恐龍展,個人還是比較喜歡坐在魚池旁,悠然自得的餵餵魚、餵餵鴿子

夕陽西下,一家和樂…
夕陽西下,一家和樂…

台灣的展覽,真的有時候會想吐血,展覽的東西了無新意,老是用一堆多媒體影像,老實說我要看的是實物或模型…那些介紹影片我在家看就一堆了。

恐龍展不是第一次辦了,去了二次,是不是同一家辦的我不知道,但這次又讓我感覺擺明就是暑假要撈錢的活動。

沒有留言:

張貼留言

Related Posts Plugin for WordPress, Blogger...
// Dnow Function