我有一个具有多个属性的类,其中我对两个属性感兴趣。请在以下示例中说PropA
和PropB
。
public class GroupByOR
{
public string PropA { get; set; }
public string PropB { get; set; }
public int SomeNumber { get; set; }
public GroupByOR(string a, string b, int num) { PropA = a; PropB = b; SomeNumber = num; }
}
我想将此类对象的列表分组,如果 <{strong> PropA
或PropB
与 <{strong> List<GroupByOR> list = new List<GroupByOR>
{
new GroupByOR("CA", "NY", 1), // Item 1
new GroupByOR("CA", "OR", 2), // Item 2
new GroupByOR("NY", "OR", 5) // Item 3
};
或AND
相匹配,则该项目的条件应属于某个组。
例如,假设我的列表如下所示:
join
然后我想要的结果就是:
第1组:第1项和第2项(基于CA)
第2组:第1项和第3项(基于纽约)
第3组:第2项和第3项(基于OR)
环顾四周,我发现了this以及其他许多示例,但它们似乎都专注于按多个属性进行分组,但使用data = self.http_pool.urlopen('GET', file_url,
preload_content=False,
retries=max_download_retries)
request.add_unredirected_header(key, header)
Add a header that will not be added to a redirected request.
操作。
我正在努力实现的目标是什么?
或者nauthorization: Basic <redacted>\r\n\r\n
还有什么方法可以去?如果是这样,请指导我朝正确的方向发展?
答案 0 :(得分:4)
你最终会得到比你开始时更多的项目,所以GroupBy并不是完整的答案。你需要这样的东西:
List<GroupByOR> list = new List<GroupByOR>
{
new GroupByOR("CA", "NY", 1), // Item 1
new GroupByOR("CA", "OR", 2), // Item 2
new GroupByOR("NY", "OR", 5) // Item 3
};
var lookupA = list.ToLookup(e => e.PropA);
var lookupB = list.ToLookup(e => e.PropB);
var keys = lookupA.Select(e => e.Key)
.Concat(lookupB.Select(e => e.Key)).Distinct();
var result = keys.Select(e =>
new
{
Key = e,
Values = lookupA[e].Concat(lookupB[e]).Distinct()
});
这会将结果投影到一个新的匿名类型,其中Key是PropA或PropB的值,而Values是IEnumerable&lt; GroupByOr&gt;所有匹配元素。
编辑:代码演练
前两个linq行使用给定的键从枚举中进行查找(实际上是多值字典)。这些可以枚举为IEnumerable&lt; IGrouping&lt; TKey,TValue&gt;&gt;,但也可用于高效查找。
var lookupA = list.ToLookup(e => e.PropA);
var lookupB = list.ToLookup(e => e.PropB);
下一行是查找PropA和PropB的所有不同值(使用查找,但也可以返回到列表中)。
var keys = lookupA.Select(e => e.Key).Concat(lookupB.Select(e => e.Key)).Distinct();
最后一行是使用不同的键,并从propA查找和propB查找中获取匹配的枚举,然后将它们连接起来,并且(现在我发现了另一个错误)对它们进行了重复删除。
select语句产生一个匿名类型 - 这些类型不能被明确引用,但可以分配给var并且可以枚举它们。如果要存储结果值,则必须创建非匿名类型。
var result = keys.Select(e =>
new
{
Key = e,
Values = lookupA[e].Concat(lookupB[e]).Distinct()
});
编辑:输出
CA
Values: (PropA: CA, PropB: NY, SomeNumber: 1) (PropA: CA, PropB: OR, SomeNumber: 2)
NY
Values: (PropA: NY, PropB: OR, SomeNumber: 5) (PropA: CA, PropB: NY, SomeNumber: 1)
OR
Values: (PropA: CA, PropB: OR, SomeNumber: 2) (PropA: NY, PropB: OR, SomeNumber: 5)