Wednesday, November 18, 2009

Encoding & Decoding Bit-Sums For a CheckBoxList

Have you ever had occasion where you need to allow users to select one or more items in a list? With ASP.Net a good UI control to do that with is the CheckBoxList. Here's a pair of examples:



Then the question arises, how do you store their selections?  If the potential list is quite long then you're probably going to want to use a CDF string of the values you've assigned to each list item - example: "2,3,11,17,34"

But for smaller, more finite lists a good way to go is with bit-encoded sums.  You assign each list item a base-2 value, such as:
  • Item A    2^0 = 1
  • Item B    2^1 = 2
  • Item C    2^2 = 4
  • Item D    2^3 = 8
In this way, when the user has finished their selection, you can add up the associated values, store that sum, and then decode it later when you return to the page again.  Thus for the aforementioned example, if the user selected A, C, & D, the sum would be: 1 + 4 + 8 = 13.

Encoding the values is very straightforward.  Here's a little algorithm that does the job:
int newSum = 0;
    foreach (ListItem item in checkBoxList.Items)
    {
      if (item.Selected)
        newSum += Convert.ToInt32(item.Value);
    }

Decoding though is somewhat trickier.  I imagine there are many possible approaches.  Here's a method I created to do the job:
private void SelectCblItems(CheckBoxList cbl, int sum)
  {
    // Determine the largest Base-2 Power that comprises sum
    int maxPower = (int)Math.Log(sum, 2);
    for (int pow = maxPower; pow >= 0; pow--)
    {
      int partSum = (int)Math.Pow(2, pow);
      if (partSum <= sum)
      {
        ListItem listItem = cbl.Items.FindByValue(partSum.ToString());
        if (listItem != null)
          listItem.Selected = true;

        sum -= partSum;
      }
    }
  }

2 comments:

  1. it can only store list with relatively small items say less than 50 or 60, since 2^64 would actually require 64bit integer. any higher values you may not be able to store them in conventional database.

    ReplyDelete
  2. good one it was really helpfull

    ReplyDelete