Home > Back-end >  Bit wise and operation on list and convert value to comma separated string
Bit wise and operation on list and convert value to comma separated string

Time:09-28

I have a list which returns an ID, Type and value. The IDs are stored as power of 2. Sample data below

var _data = await _context.clubs.Where(x => x.Type == "NewTown").ToListAsync();
ID Type Value
1 NewTown Test1
2 NewTown Test2
4 NewTown Test3

I have a view model which stores IDs from this table by adding them like if I select first and third it will save 5 similarly if I select first and second it will save 3.

These values will be saved in a different table where I can't store the Ids as comma separated values because it would eventually b sent as a token and if I have many fields the token would exceed the length that's why I'm saving the sum of the Ids.

Now what I want to do is while displaying these values I want to show Test1 , Test3 if 5 is saved. Now I know if I do a bit wise and operation with the array and the selected value it will give me the values like this example below.

var savedVal= 5;
var testArray = new int[] {1,2,4,8,16,32,64,128};
testArray .Select(x => new { savedVal= x, Enabled = ((savedVal & x) > 0) }).Dump();
savedVal Enabled
1 True
2 False
4 True
8 False
16 False
32 False
64 False
128 False

This will give me enabled "true" for the values that were selected.

Now what I want to know is how can I achieve this for my list scenario where I have 3 fields in the list and I want to have the values of enabled ones as a comma-separated string like "Test1, Test3" for the example I shared.

CodePudding user response:

Using a combination of Linq: Join, Where, Select, ToArray, with String.Join to produce a list of Test Values from the DBContext by joining your returned list of savedVals where Enabled = true

//a test object to simulate your DBContext
var testdbcontext = new List<dynamic> 
{ 
    new { Id = 1, Type = "NewTown", Value = "Test1" }, 
    new { Id = 2, Type = "NewTown", Value = "Test2" }, 
    new { Id = 4, Type = "NewTown", Value = "Test3" }
};

var savedVal= 5;
var testArray = new int[] {1,2,4,8,16,32,64,128};

Console.WriteLine(String.Join(",", 
    testdbcontext
   .Join(testArray.Select(x => new { savedVal= x, Enabled = ((savedVal & x) > 0) })
   .Where(b => b.Enabled)
   .Select(c => c.savedVal),
                a => a.Id,
                b => b,
                (a, b) => new string (a.Value)).ToArray()));

Prints:

//Test1,Test3

CodePudding user response:

The previous answer is definitely correct, buy might be a bit confusing/too complex for beginners. You literally only missed String.Join method to achieve your goal. My version of code to solve you issue is:

...(your code)

var _data = await _context
    .clubs
    .Where(x => x.Type == "NewTown")
    .Where (x => (savedVal & x) > 0)
    .ToListAsync();

resultString = String.Join(',', _data.Select(x => x.Value));
  • Related