我有一堂课说
public class Sample
{
public string property;
public List<string> someListProperty;
public string someOtherPropery;
}
现在我有一个List<Sample>
的对象,我需要迭代这个集合,找出property
和someListProperty
字段具有相同值的项目。
我试过了:
var listSample = List<Sample>()
var result = listSample.GroupBy(x => new { x.property, x.someListProperty})
.Where(x => x.Count() > 1).ToList();
但这似乎不起作用,任何指针都会受到高度赞赏。
答案 0 :(得分:2)
以下评论后更新:正如您所描述的那样,您希望按someOtherProperty
而不是someListProperty
分组,然后按其分组:
listSample.GroupBy(x => new { x.property, x.someOtherProperty});
选项1 - 您应该使用SequenceEqual
检查两个给定样本的嵌套列表是否相同。为此,请传递自定义IEqualityComparer
public class SampleComparer : IEqualityComparer<Sample>
{
public bool Equals(Sample x, Sample y)
{
return x.property == y.property &&
Enumerable.SequenceEqual(x.someListProperty, y.someListProperty);
}
public int GetHashCode(Sample obj)
{
// Implement
}
}
(用于实施GetHashCode
请参阅:What is the best algorithm for an overridden System.Object.GetHashCode?)
然后:
var result = list.GroupBy(k => k, new SampleComparer());
测试了以下数据并返回3组:
List<Sample> a = new List<Sample>()
{
new Sample { property = "a", someListProperty = new List<string> {"a"}, someOtherPropery = "1"},
new Sample { property = "a", someListProperty = new List<string> {"a"}, someOtherPropery = "2"},
new Sample { property = "a", someListProperty = new List<string> {"b"}, someOtherPropery = "3"},
new Sample { property = "b", someListProperty = new List<string> {"a"}, someOtherPropery = "4"},
};
选项2 - 不是创建实现界面的类,而是使用ProjectionEqualityComparer
,如下所述:Can you create a simple 'EqualityComparer<T>' using a lambda expression
作为旁注,而不是在使用中使用Count
:
var result = list.GroupBy(k => k, new SampleComparer())
.Where(g => g.Skip(1).Any());
正如你想要的只是检查组中有多个项目而不是实际数量,这只会通过两个项目,而不是在O(n)
操作中计算所有项目。
答案 1 :(得分:0)
像这样调整你的linq:
static void Main(string[] args)
{
var samples = new List<Sample>
{
new Sample("p1", "aaa,bbb,ccc,ddd"),
new Sample("p1", "bbb,ccc,xxx"),
new Sample("p2", "aaa,bbb,ccc"),
new Sample("p1", "xxx")
};
var grp = samples.GroupBy(b => b.property)
.Where(a => a.Key == "p1")
.SelectMany(s => s.ToList())
.Where(b => b.someListProperty.Contains("ccc"));
foreach (var g in grp)
System.Console.WriteLine(g.ToString());
System.Console.ReadLine();
}
private class Sample
{
public string property;
public List<string> someListProperty;
public string someOtherPropery;
public Sample(string p, string props)
{
property = p;
someListProperty = props.Split(',').ToList();
someOtherPropery = string.Concat(from s in someListProperty select s[0]);
}
public override string ToString()
{
return $"{property} - {string.Join(", ", someListProperty)} -"
+ $" ({someOtherPropery})";
}
}
误读 - 我读过你想要那些&#34;一些&#34; someListProperty
的{{1}}应该是您要从分组中过滤的那些。
你可以像这样分组以实现它:
var grp = samples
// choose a joiner thats not in your somePropertyList-data
.GroupBy(b => $"{b.property}:{string.Join("|", b.someListProperty)}")
.Where(g => g.Skip(1).Any())
.SelectMany(s => s.ToList())
但请注意,这有点hackish,取决于您的数据。你基本上将所有有趣的东西分组,然后选择所有有多种结果的东西。