I'm sure there must be a much better way of doing this. I'm trying to do a count operation on a Flags enum. Before I was itterating over all the possible values and counting the succesful AND operations.
e.g.
[Flags]
public enum Skills
{
None = 0,
Skill1 = 1,
Skill2 = 2,
Skill3 = 4,
Skill4 = 8,
Skill5 = 16,
Skill6 = 32,
Skill7 = 64,
Skill8 = 128
}
public static int Count(Skills skillsToCount)
{
Skills skill;
for (int i = 0; i < SkillSet.AllSkills.Count; i++)
{
skill = SkillSet.AllSkills[i];
if ((skillsToCount & skill) == skill && skill != Skills.None)
count++;
}
return count;
}
I'm sure there must be a better way of doing this though, but must be suffering from a mental block. Can anyone advise a nicer solution?
After looking on the site Assaf suggested I managed to find a slightly different solution that I got working for Int32's.
Here's the code for anyone else:
A very concise way to do it using
BitArray
and LINQ:If you're targeting .NET Core 3.0 or above, you can use
BitOperations.PopCount()
, it operates inuint
orulong
and returns the number of1
bits.If your CPU supports SSE4, it'll use the
POPCNT
CPU instruction, otherwise it'll use a software fallback.the only reason to use this method is if the flags are not contiguous and if flags will be added periodically.
if "better" means faster this ain't ;) it.
The count is equivalent to counting how many bits are set to 1 in the integer value of the enum.
There are very fast ways of doing this in C/C++, which you can adapt to C#:
e.g.
Taken from here.
EDIT
Provided link is dead. Found another one that probably contains the same content.