C# 如何在不使用循环声明方式的情况下仅获取纯记录
我有一些买自行车的人。 这张桌子看起来像 我想得到的用户谁只买了相同的自行车。 此示例的输出必须为,因为PeopleID 2没有其他颜色 2红色 这个班是C# 如何在不使用循环声明方式的情况下仅获取纯记录,c#,linq,C#,Linq,我有一些买自行车的人。 这张桌子看起来像 我想得到的用户谁只买了相同的自行车。 此示例的输出必须为,因为PeopleID 2没有其他颜色 2红色 这个班是 class Foo { public String PeopleID { get; set; } public String Bicycle { get; set; } } 功能是 static void WhoBuyedSameBike(IEnumerable<Foo> foo
class Foo
{
public String PeopleID { get; set; }
public String Bicycle { get; set; }
}
功能是
static void WhoBuyedSameBike(IEnumerable<Foo> foos)
{
var tmpFoos = foos;
var result = tmpFoos.GroupBy(x => x.PeopleID);
var queryResult = new List<QueryResult>();
foreach (var fooItem in result)
{
if (fooItem.Count() == tmpFoos.Count(w => w.PeopleID == fooItem.Key && w.Bicycle == "Red"))
{
queryResult.Add(new QueryResult { PeopleID = fooItem.Key });
}
}
foreach (var item in queryResult)
{
Console.WriteLine($"PeopleId : {item.PeopleID}");
}
}
静态void whobuedsamebike(IEnumerable foos)
{
var tmpFoos=foos;
var result=tmpFoos.GroupBy(x=>x.PeopleID);
var queryResult=新列表();
foreach(结果中的项目)
{
if(fooItem.Count()==tmpFoos.Count(w=>w.PeopleID==fooItem.Key&&w.Bicycle==Red))
{
添加(新的queryResult{PeopleID=fooItem.Key});
}
}
foreach(queryResult中的var项)
{
WriteLine($“PeopleId:{item.PeopleId}”);
}
}
对于更多的声明性代码,有没有其他方法可以不使用foreach循环和Linq来获得输出 使用Linq,按每个人分组,获得每个自行车颜色的不同计数,并从计数为1的每组中选择第一个(唯一)项目
IEnumerable<Foo> result =
foos
.GroupBy(foo => foo.PeopleID)
.Where(group => group.Select(foo => foo.Bicycle).Distinct().Count() == 1)
.Select(group => group.First());
编辑 在注释中,Harald Coppoolse建议在where语句中进行计数之前插入.Take(2)。这将更有效,因为.Count()必须枚举整个集合才能获得大小(除非它实现ICollection)。他还提出了第二种更有效的方法 然而,当我们进行此操作时,我想我会更进一步,将嵌套的Select和Distinct方法压缩到一个聚合中,结果不需要重新迭代以确定是否存在重复
foos
.GroupBy(foo => foo.PeopleID)
.Where(group => group.Aggregate((a,b) => a?.Bicycle == b.Bicycle ? a : null) != null)
.Select(group => group.First());
当然,这只是为了更好地理解。当然,在了解聚合方法、terneray运算符和null条件运算符之前,首先要了解原始版本
顺便说一下。我之前没有提到,如果性能比可读性或代码优雅更重要,那么不要逃避for循环。上面的代码在没有这个限制的情况下仍然可以更有效。您真的不应该迭代作为输入提供的任意
IEnumerable
。你不知道迭代多次是否昂贵,迭代多次是否会产生不同的结果,迭代多次是否会出现错误,等等。我同意你的观点,但这是一个面试问题。我的代码编写方式一直萦绕在我的脑海中。什么是QueryResult
?我发现在处理嵌套或递归时,编码可能会变得困难。在这种情况下,在where语句中执行select可能会使您感到不适。所以一定要找出这些谜题来磨练你在未来面试中的技能。你是绝对正确的。这就是为什么我要努力提高我的代码编写技能。我的代码也能工作,但我必须知道更好的方法。现在我真的很高兴再次感谢。代替使用CONTUTE()来查看是否只有一个项目,考虑使用<代码>。取(2)。COUNTHER(=)=1 < /代码>,这样你就不必数别人买的所有1000辆自行车。在第二辆自行车上,你已经知道不止一辆了。效率更高:Where not。跳过(1).Any()
@haraldcopoolse,你启发我添加一个新版本。想知道你对它的看法。Aggregate
的使用很好,但是要知道这只适用于AsEnumerable
<代码>可查询。实体框架不支持聚合
foreach(var foo in result) {
Console.WriteLine($"PeopleId:{foo.PeopleID}, Bicycle:{foo.Bicycle}");
}
foos
.GroupBy(foo => foo.PeopleID)
.Where(group => group.Aggregate((a,b) => a?.Bicycle == b.Bicycle ? a : null) != null)
.Select(group => group.First());