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?
There's a straight-forward way using functional programming (LINQ):
It might be a bit slower than the bit-juggling solutions, but it's still allocation-free, has a constant run-time and is more intuitive.
The following code will give you the number of bits that are set for a given number of any type varying in size from byte up to long.
This code is very efficient as it only iterates once for each bit rather than once for every possible bit as in the other examples.
depends on the definition of "better".
the check for Skills.None is required because if no bits are on, the string() returns Skills.None which results in a count of 1. this would work the same for integer, long, and their unsigned relatives.