欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用位運算實現(xiàn)網(wǎng)頁中的過濾、篩選功能實例

 更新時間:2014年07月16日 10:06:41   投稿:junjie  
這篇文章主要介紹了使用位運算實現(xiàn)網(wǎng)頁中的過濾、篩選功能實例,一個比常規(guī)拼接SQL字符串更有新意的一個解決思路,需要的朋友可以參考下

最近屌絲的公司想要為以前的那個網(wǎng)頁產(chǎn)品加上一個過濾的功能,廢話不多說,直接看篩選的界面是啥樣的吧:

可以看出,我們的Message分為Critical、Error等6種類型?,F(xiàn)在需要進行過濾,用戶可以選擇查看其中的一項或多項。

這種需求是很常見的,在大多數(shù)情況下,如果可選項是不固定的(比如對于學生信息管理系統(tǒng),按照班級進行篩選),那么就可能需要借助復雜的SQL語句。例如我們可以寫成如下這種形式:

復制代碼 代碼如下:

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

這樣就要對SQL語句進行拼接,根據(jù)用戶選擇了哪些內(nèi)容來動態(tài)生成SQL語句。

假如不是數(shù)據(jù)庫操作,而是內(nèi)存中一片數(shù)據(jù)的判斷,假如用戶選擇的內(nèi)容存放在Selected[]數(shù)組中,那么對于需要判斷的每一項,我們都需要進行一連串的判斷操作,需要寫一個雙重循環(huán)。不僅寫起來比較復雜,如果項目過多在效率上也令人堪憂。

如果我們需求是像上圖那樣,Type是固定的并且也不會很多,那么有沒有一種比較簡單的方式呢?

從標題可以看出,可以使用位運算。在各類高級語言的源代碼中大量地運用了這種方式。對于可枚舉類型,取值不是順序的1、2、3、4,而是1、2、4、8按照2的倍數(shù)增長,這就是使用二進制位進行判斷。

現(xiàn)在我用我剛做的東西來簡單敘述一下如何實現(xiàn)吧。當然實現(xiàn)這個很簡單,在這里記錄更多地是為了增加博文的數(shù)量^_^。

在.NET中,一個int類型占4個字節(jié),也就是32位,除去符號位(當然也可以使用無符號整數(shù),這里為了簡單期間都使用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三種類型,把這三個數(shù)字相加,就是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;

當然,由于這種特殊的設計,使用加法運算的效果是完全相同的。

這樣把用戶選擇的內(nèi)容傳給服務器就是一個簡單的整數(shù),比如上面的13表示用戶選擇的三種類型。而且在數(shù)學上可以證明,對于每一個整數(shù),對應的枚舉類型的組合是唯一的(要證明看似很難,但如果使用二進制進行思考便會顯而易見)。

在服務器端對每種消息進行判斷時,只需要使用與運算,便能知道消息是否在用戶選擇的范圍內(nèi)(只要結(jié)果不等于0,說明某個枚舉類型對應的那一位在相加的結(jié)果中。如果使用符號位,那么可能會出現(xiàn)負數(shù))。

舉兩個簡單的例子吧,假如客戶端傳過來的是13(0000 1101),某一種消息是Waring=8(0000 1000),相與的結(jié)果為8(0000 1000)與消息的類型相同(只需判斷是否不等于0即可)。對于消息為16(0001 0000)的情況,相與的結(jié)果肯定是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的數(shù)字即可(0x7fffffff,如果使用符號位就是0xffffffff)。

在客戶段根據(jù)這個相加后的結(jié)果進行控件綁定的使用,要判斷某個復選框是否應該選中時,按照相同的邏輯相與即可:

復制代碼 代碼如下:

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);

需要注意的是,這個方法不是萬能的。如果可選項是不固定的,使用位運算有可能反而會很麻煩,因為我們要編寫程序存儲每一種選項對應的數(shù)字。

如果可選項是固定的但是數(shù)量很多(比如幾千種),那么我們可以用一串整數(shù)進行表示,也會很方便(當然顯示也不會有這樣變態(tài)的篩選功能,即使有用戶也不大可能在幾千種里面去選,如果出現(xiàn)這種情況,只能說設計有問題)。

這種做法有一個比較大的弊端,就是改動篩選內(nèi)容時服務器和客戶端都會改。不過還好改動不會太大,只需要改變服務器的enum和客戶端的控件即可……

當然這種思想也是今后設計程序時的一種很好參考。

相關(guān)文章

  • C# 多態(tài)性的深入理解

    C# 多態(tài)性的深入理解

    本篇文章是對C#中的多態(tài)性進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • 詳細聊聊C#的并發(fā)機制優(yōu)秀在哪

    詳細聊聊C#的并發(fā)機制優(yōu)秀在哪

    并發(fā)其實是一個很泛的概念,字面意思就是"同時做多件事",不過方式有所不同,下面這篇文章主要給大家介紹了關(guān)于C#并發(fā)機制的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-02-02
  • C#發(fā)送Get、Post請求(帶參數(shù))

    C#發(fā)送Get、Post請求(帶參數(shù))

    本文主要介紹了C#發(fā)送Get、Post請求,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • C#中的Hashtable?類使用詳解

    C#中的Hashtable?類使用詳解

    這篇文章主要介紹了C#中的Hashtable?類使用詳解,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • 基于Aforge攝像頭調(diào)用簡單實例

    基于Aforge攝像頭調(diào)用簡單實例

    這篇文章主要為大家詳細介紹了基于Aforge攝像頭調(diào)用的簡單實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • C# 中文簡體轉(zhuǎn)繁體實現(xiàn)代碼

    C# 中文簡體轉(zhuǎn)繁體實現(xiàn)代碼

    C# 中文簡體轉(zhuǎn)繁體實現(xiàn)代碼,需要的朋友可以參考一下
    2013-02-02
  • C#操作數(shù)據(jù)庫總結(jié)(vs2005+sql2005)

    C#操作數(shù)據(jù)庫總結(jié)(vs2005+sql2005)

    C#操作數(shù)據(jù)庫總結(jié),每次做項目都會用到數(shù)據(jù)庫,對數(shù)據(jù)庫的操作都是糊里糊涂從書里找代碼用。通過昨天晚上與今天早上的努力,把數(shù)據(jù)庫的操作整理了一下,下面把整理結(jié)果做個小結(jié)
    2012-09-09
  • C#截圖程序類似騰訊QQ截圖實現(xiàn)代碼

    C#截圖程序類似騰訊QQ截圖實現(xiàn)代碼

    拖動過程中顯示當前鼠標下一小塊的圖像信息 尺寸、顏色信息的 注意 這里顏色是用的ARGB,需要的朋友可以參考下
    2012-12-12
  • C#分屏控件用法實例

    C#分屏控件用法實例

    這篇文章主要介紹了C#分屏控件用法實例,需要的朋友可以參考下
    2014-08-08
  • c# 常見文件路徑Api的使用示例

    c# 常見文件路徑Api的使用示例

    c#編程中經(jīng)常有遇到要處理文件路徑的需求,本文分別講述了如何從程序下面的文件和臨時目錄下的文件去使用路徑api,感興趣的朋友可以了解下
    2021-05-05

最新評論