程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 應用位運算完成網頁中的過濾、挑選功效實例

應用位運算完成網頁中的過濾、挑選功效實例

編輯:C#入門知識

應用位運算完成網頁中的過濾、挑選功效實例。本站提示廣大學習愛好者:(應用位運算完成網頁中的過濾、挑選功效實例)文章只能為提供參考,不一定能成為您想要的結果。以下是應用位運算完成網頁中的過濾、挑選功效實例正文


比來屌絲的公司想要為之前的誰人網頁產物加上一個過濾的功效,空話不多說,直接看挑選的界面是啥樣的吧:

可以看出,我們的Message分為Critical、Error等6品種型。如今須要停止過濾,用戶可以選擇檢查個中的一項或多項。

這類需求是很罕見的,在年夜多半情形下,假如可選項是不固定的(好比關於先生信息治理體系,依照班級停止挑選),那末便可能須要借助龐雜的SQL語句。例如我們可以寫成以下這類情勢:

SELECT * FROM [Student] WHERE [ClassId] = 1 OR [ClassId] = 2 OR...

如許就要對SQL語句停止拼接,依據用戶選擇了哪些內容來靜態生成SQL語句。

假設不是數據庫操作,而是內存中一片數據的斷定,假設用戶選擇的內容寄存在Selected[]數組中,那末關於須要斷定的每項,我們都須要停止連續串的斷定操作,須要寫一個兩重輪回。不只寫起來比擬龐雜,假如項目過量在效力上也使人堪憂。

假如我們需求是像上圖那樣,Type是固定的而且也不會許多,那末有無一種比擬簡略的方法呢?

從題目可以看出,可使用位運算。在各類高等說話的源代碼中年夜量地應用了這類方法。關於可列舉類型,取值不是次序的1、2、3、4,而是1、2、4、8依照2的倍數增加,這就是應用二進制位停止斷定。

如今我用我剛做的器械來簡略論述一下若何完成吧。固然完成這個很簡略,在這裡記載更多地是為了增長博文的數目^_^。

在.NET中,一個int類型占4個字節,也就是32位,除去符號位(固然也能夠應用無符號整數,這裡為了簡略時代都應用int),每位都可以標識一個新聞的類型。為此,我們界說列舉類型以下:

public enum CategoryType: int
{
    Unknown = 1,
    Critical = 2,
    Error = 4,
    Warning = 8,
    Information = 16,
    Verbose = 32,
    Other = 1024
}

假如用二進制表現,這些新聞分離是0000 0001、0000 0010、0000 0100、0000 1000、00010000、…… 假設用戶選擇了Unknown、Error和Waring三品種型,把這三個數字相加,就是1+4+8=13,二進制表現就是0000 1101。為1的位正好對應了用戶選擇的類型,為0的位正好對用用戶沒選的類型。

在客戶端,應用Javascript便可以應用上面這類簡略的方法盤算用戶選擇的值:

var category = 0;

if (filterVM.ckType2Checked()) category |= 2;
if (filterVM.ckType4Checked()) category |= 4;
if (filterVM.ckType8Checked()) category |= 8;
if (filterVM.ckType16Checked()) category |= 16;
if (filterVM.ckType32Checked()) category |= 32;
if (filterVM.ckType1024Checked()) category |= 1024;

固然,因為這類特別的設計,應用加法運算的後果是完整雷同的。

如許把用戶選擇的內容傳給辦事器就是一個簡略的整數,好比下面的13表現用戶選擇的三品種型。並且在數學上可以證實,關於每個整數,對應的列舉類型的組合是獨一的(要證實看似很難,但假如應用二進制停止思慮便會不言而喻)。

在辦事器端對每種新聞停止斷定時,只須要應用與運算,便能曉得新聞能否在用戶選擇的規模內(只需成果不等於0,解釋某個列舉類型對應的那一名在相加的成果中。假如應用符號位,那末能夠會湧現正數)。

舉兩個簡略的例子吧,假設客戶端傳過去的是13(0000 1101),某一種新聞是Waring=8(0000 1000),相與的成果為8(0000 1000)與新聞的類型雷同(只需斷定能否不等於0便可)。關於新聞為16(0001 0000)的情形,相與的成果確定是0。代碼以下:

for (int i = 0; i < list.Count; i++)
{
    if (((int)list[i].Category & categoryFilter) > 0 && ((int)list[i].Direction & directionFilter) > 0)
        yield return list[i];
}

關於要選出一切的類型的情形,只須要把上述categoryFilter設置為全體為1的數字便可(0x7fffffff,假如應用符號位就是0xffffffff)。

在客戶段依據這個相加後的成果停止控件綁定的應用,要斷定某個復選框能否應當選中時,依照雷同的邏輯相與便可:


this.ckType2Checked((category & 2) > 0);
this.ckType4Checked((category & 4) > 0);
this.ckType8Checked((category & 8) > 0);
this.ckType16Checked((category & 16) > 0);
this.ckType32Checked((category & 32) > 0);
this.ckType1024Checked((category & 1024) > 0);

須要留意的是,這個辦法不是全能的。假如可選項是不固定的,應用位運算有能夠反而會很費事,由於我們要編寫法式存儲每種選項對應的數字。

假如可選項是固定的然則數目許多(好比幾千種),那末我們可以用一串整數停止表現,也會很便利(固然顯示也不會有如許失常的挑選功效,即便有效戶也不年夜能夠在幾千種外面去選,假如湧現這類情形,只能說設計有成績)。

這類做法有一個比擬年夜的弊病,就是修改挑選內容時辦事器和客戶端都邑改。不外還好修改不會太年夜,只須要轉變辦事器的enum和客戶真個控件便可……

固然這類思惟也是往後設計法式時的一種很好參考。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved