C# 枚举 - 给定一个 int 输入猜测标志
C# Enum - Guessing Flags given an int input
假设我们有以下标志枚举:
[Flags]
public enum Animals
{
Cow = 1,
Duck = 2,
Goose = 4
}
现在,给定这个枚举,我们想要指定一个函数,将 int 作为输入,给定这个数字,我们想要 return 一个包含这个数字包含的动物的数组。
例如,如果我们收到数字 7 作为输入,我们就知道我们有奶牛、鸭子和鹅,因为 4+2+1 = 7。
对于此枚举中出现的任意数量的动物,我们如何确定该数量中包含哪些动物?
public static IEnumerable<Animals> GetAnimals(int i)
{
var animals = (Animals) i;
foreach (Enum value in Enum.GetValues(animals.GetType()))
if (animals.HasFlag(value))
yield return (Animals) value;
}
Fiddle: https://dotnetfiddle.net/yydUE2
通用版本 - 不是太快,可能会有所改进...
void Main()
{
var flags = Ext.GetFlags<Animal>(7);
flags.Dump();
}
public static class Ext
{
public static IEnumerable<T> GetFlags<T>(int flags)
where T : struct
{
return typeof(T).GetEnumValues().Cast<T>()
.Where(a => ((dynamic)(T)(object)flags).HasFlag(a)).ToList();
}
}
[Flags]
public enum Animal
{
Cow =1,
Duck = 2,
Goose = 4,
Dog = 8
}
正如其他人所说,绝大多数情况下没有单一的答案,但举个例子,我假设你想要一个贪婪的猜测算法来 return 大值动物的最小数量:
void Main()
{
int test = 21;
var allAnimals = (Animal[]) Enum.GetValues(typeof(Animal));
var ordered = allAnimals.OrderByDescending(x => x);
var animals = ordered.Aggregate(new List<Animal>(), (agg, ani) => {
if (test > 0) {
int number = (int)(test / (int)ani);
agg.AddRange(Enumerable.Repeat(ani, number));
test -= number * (int)ani;
}
return agg;
});
Console.WriteLine(string.Join(", ", animals.Select(a=>a.ToString())));
}
[Flags]
public enum Animal
{
Cow = 1,
Duck = 2,
Goose = 4
}
假设我们有以下标志枚举:
[Flags]
public enum Animals
{
Cow = 1,
Duck = 2,
Goose = 4
}
现在,给定这个枚举,我们想要指定一个函数,将 int 作为输入,给定这个数字,我们想要 return 一个包含这个数字包含的动物的数组。
例如,如果我们收到数字 7 作为输入,我们就知道我们有奶牛、鸭子和鹅,因为 4+2+1 = 7。
对于此枚举中出现的任意数量的动物,我们如何确定该数量中包含哪些动物?
public static IEnumerable<Animals> GetAnimals(int i)
{
var animals = (Animals) i;
foreach (Enum value in Enum.GetValues(animals.GetType()))
if (animals.HasFlag(value))
yield return (Animals) value;
}
Fiddle: https://dotnetfiddle.net/yydUE2
通用版本 - 不是太快,可能会有所改进...
void Main()
{
var flags = Ext.GetFlags<Animal>(7);
flags.Dump();
}
public static class Ext
{
public static IEnumerable<T> GetFlags<T>(int flags)
where T : struct
{
return typeof(T).GetEnumValues().Cast<T>()
.Where(a => ((dynamic)(T)(object)flags).HasFlag(a)).ToList();
}
}
[Flags]
public enum Animal
{
Cow =1,
Duck = 2,
Goose = 4,
Dog = 8
}
正如其他人所说,绝大多数情况下没有单一的答案,但举个例子,我假设你想要一个贪婪的猜测算法来 return 大值动物的最小数量:
void Main()
{
int test = 21;
var allAnimals = (Animal[]) Enum.GetValues(typeof(Animal));
var ordered = allAnimals.OrderByDescending(x => x);
var animals = ordered.Aggregate(new List<Animal>(), (agg, ani) => {
if (test > 0) {
int number = (int)(test / (int)ani);
agg.AddRange(Enumerable.Repeat(ani, number));
test -= number * (int)ani;
}
return agg;
});
Console.WriteLine(string.Join(", ", animals.Select(a=>a.ToString())));
}
[Flags]
public enum Animal
{
Cow = 1,
Duck = 2,
Goose = 4
}