C# 按其持有的项目对项目进行分组
请注意:我的问题包含伪代码 我的军队里有步兵。 每个士兵都是独一无二的:名字、力量等等 所有士兵都有库存。它可以是空的。 库存可以包含:武器、盾牌、其他物品 我想根据步兵的确切数量对他们进行分组 非常简单的示例: 我收集了:C# 按其持有的项目对项目进行分组,c#,algorithm,sorting,grouping,C#,Algorithm,Sorting,Grouping,请注意:我的问题包含伪代码 我的军队里有步兵。 每个士兵都是独一无二的:名字、力量等等 所有士兵都有库存。它可以是空的。 库存可以包含:武器、盾牌、其他物品 我想根据步兵的确切数量对他们进行分组 非常简单的示例: 我收集了: 武器:{“AK-47”、“手榴弹”、“刀”} 盾牌:{“宙斯盾”} 其他项目:{“Kevlavest”} 步兵的集合。(计数=6) “乔”:{“AK-47”,“凯夫拉尔背心”} “弗雷德”:{“AK-47”} “约翰”:{“AK-47”,“手榴弹”} “兰博”:{“刀
- 武器:{“AK-47”、“手榴弹”、“刀”}
- 盾牌:{“宙斯盾”}
- 其他项目:{“Kevlavest”}
- “乔”:{“AK-47”,“凯夫拉尔背心”}
- “弗雷德”:{“AK-47”}
- “约翰”:{“AK-47”,“手榴弹”}
- “兰博”:{“刀”}
- “Foo”:{“AK-47”}
- “Bar”:{“Kevlavest”}
- {“AK-47”}
- {“AK-47”,“手榴弹”}
- {“AK-47”,“凯夫拉尔背心”}
- {“刀”}
- {“Kevlavest”}
GetSoldierGroupings
方法,使TestSoldierGroupings
方法成功?
public class FootSoldier
{
public string Name { get; set; }
public string[] Inventory { get; set; }
}
public class ArrayComparer<T> : IEqualityComparer<T[]>
{
public bool Equals(T[] x, T[] y)
{
return x.SequenceEqual(y);
}
public int GetHashCode(T[] obj)
{
return obj.Aggregate(string.Empty, (s, i) => s + i.GetHashCode(), s => s.GetHashCode());
}
}
[TestMethod]
public void TestSoldierGroupings()
{
//Arrange
var weapons = new[] { "AK-47", "Grenade", "Knife" };
var shields = new[] { "Aegis" };
var otherItems = new[] { "KevlarVest" };
var footSoldiers = new FootSoldier[]
{
new FootSoldier() { Name="Joe" , Inventory= new string[]{ "AK-47", "Kevlar Vest" } },
new FootSoldier() { Name="Fred" , Inventory= new string[]{ "AK-47" } },
new FootSoldier() { Name="John" , Inventory= new string[]{ "AK-47", "Grenade" } },
new FootSoldier() { Name="Rambo" , Inventory= new string[]{ "Knife" } },
new FootSoldier() { Name="Foo" , Inventory= new string[]{ "AK-47" } },
new FootSoldier() { Name="Bar" , Inventory= new string[]{ "Kevlar Vest" } }
};
//Act
var result = GetSoldierGroupings(footSoldiers, weapons, shields, otherItems);
//Assert
Assert.AreEqual(result.Count, 5);
Assert.AreEqual(result.First().Key, new[] { "AK-47" });
Assert.AreEqual(result.First().Value.Count(), 2);
Assert.AreEqual(result.Last().Key, new[] { "Kevlar Vest" });
Assert.AreEqual(result[new[] { "Knife" }].First().Name, "Rambo");
}
public Dictionary<string[], FootSoldier[]> GetSoldierGroupings(FootSoldier[] footSoldiers,
string[] weapons,
string[] shields,
string[] otherItems)
{
//var result = new Dictionary<string[], FootSoldier[]>();
var result = footSoldiers
.GroupBy(fs => fs.Inventory, new ArrayComparer<string>())
.ToDictionary(x => x.Key, x => x.ToArray());
//TODO: the actual sorting.
return result;
}
公共级步兵
{
公共字符串名称{get;set;}
公共字符串[]清单{get;set;}
}
公共类阵列比较程序:IEqualityComparer
{
公共布尔等于(T[]x,T[]y)
{
返回x.x(y);
}
public int GetHashCode(T[]obj)
{
返回obj.Aggregate(string.Empty,(s,i)=>s+i.GetHashCode(),s=>s.GetHashCode());
}
}
[测试方法]
public void TestSoldierGroupings()
{
//安排
var武器=新[]{“AK-47”、“手榴弹”、“刀”};
var shields=new[]{“宙斯盾”};
var otherItems=new[]{“Kevlavest”};
var步兵=新步兵[]
{
新步兵(){Name=“Joe”,Inventory=newstring[]{“AK-47”,“Kevlar背心”},
新步兵(){Name=“Fred”,Inventory=newstring[]{“AK-47”},
新步兵(){Name=“John”,Inventory=newstring[]{“AK-47”,“手榴弹”},
新步兵(){Name=“Rambo”,Inventory=newstring[]{“刀”},
新步兵(){Name=“Foo”,Inventory=newstring[]{“AK-47”},
新步兵(){Name=“Bar”,库存=新字符串[]{“Kevlar背心”}
};
//表演
var结果=获取士兵分组(步兵、武器、盾牌、其他物品);
//断言
Assert.AreEqual(result.Count,5);
AreEqual(result.First().Key,new[]{“AK-47”});
Assert.AreEqual(result.First().Value.Count(),2);
AreEqual(result.Last().Key,new[]{“Kevlar Vest”});
AreEqual(result[new[]{“Knife”}).First().Name,“Rambo”);
}
公共字典GetSoldierGroup(步兵[]步兵,
弦[]武器,
字符串[]屏蔽,
字符串[]其他项)
{
//var result=newdictionary();
var结果=步兵
.GroupBy(fs=>fs.Inventory,新的ArrayComparer())
.ToDictionary(x=>x.Key,x=>x.ToArray());
//TODO:实际排序。
返回结果;
}
您需要按组合物品键将士兵分组。可以使用自定义比较器进行此操作。对我来说,我会使用
String.Join
和分隔符,这在任何武器、盾牌等中都不会遇到
假设士兵有一个属性Items
,它是一个字符串数组(如[“AK-47”,“Kevlar背心”]
),您可以这样做:
var groups = soldiers
.GroupBy(s => String.Join("~~~", s.Items))
.ToDictionary(g => g.First().Items, g => g.ToArray());
它将生成一个字典,其中键是唯一的项集,值是拥有该项集的所有士兵的数组
您可以更改此代码,使其返回i分组
、类数组\structs、字典
,任何其他方便的内容。我想要一本
字典
或者一个类似于士兵项目组[]
的数组,其中物品和士兵是属性。确保更改这样的连接分隔符,使理论上没有武器可以容纳它。Ohhh如果步兵的库存中没有物品,那是他们自己的一组,在排序的基础上:-)您可以枚举库存项目的可能组合,并将该枚举作为士兵声音的属性,如使用自定义比较器的标准LINQ
GroupBy
。你试过什么吗?有什么问题?@Tony_KiloPapaMikeGolf:根据您删除的问题:\u appleTrees.SelectMany(atree=>atree.Basket.Apples.Where(a=>a.DNA.Contains(atree.TreeDNA))代码>@TimSchmelter:谢谢你的帮助!我不敢回答问题,人们的投票速度太快了。我用过你的ToDictionary()方法。但我不得不加上一句:“公共类ArrayComparer:IEqualityComparer”。你能帮我排序吗,这样TestMethod就成功了?