使用 LINQ 进行高级分组和聚合
本文关键字:高级 LINQ 使用 | 更新日期: 2023-09-27 18:36:52
>我有下面的程序:
void Main()
{
List<Online_video_for_programmers> current_year_videos = new List<Online_video_for_programmers>()
{
new Online_video_for_programmers
{
video_name="websocket for fortran programmers",
season=2,
seasontype=1,
year=2012
},
new Online_video_for_programmers
{
video_name="cross site scripting for facebook addicts",
season=3,
seasontype=2,
year=2012
},
new Online_video_for_programmers
{
video_name="Artificial intelligence for self aware robots",
season=1,
seasontype=1,
year=2012
}
,
new Online_video_for_programmers
{
video_name="Artificial intelligence for self aware robots",
season=3,
seasontype=1,
year=2012
},
new Online_video_for_programmers
{
video_name="Artificial intelligence for adavanced robots",
season=5,
seasontype=1,
year=2012
},
new Online_video_for_programmers
{
video_name="Yoga for programmers",
season=2,
seasontype=2,
year=2012
},
new Online_video_for_programmers
{
video_name="Yoga for programmers",
season=3,
seasontype=2,
year=2012
}
};
//Last years videos sold
List<Online_video_for_programmers> last_year_videos = new List<Online_video_for_programmers>()
{
new Online_video_for_programmers
{
video_name="websocket for fortran programmers",
season=2,
seasontype=1,
year=2011,
},
new Online_video_for_programmers
{
video_name="cross site scripting for facebook addicts",
season=3,
seasontype=1,
year=2011,
},
new Online_video_for_programmers
{
video_name="Artificial intelligence for self aware robots",
season=2011,
seasontype=3,
year=2011,
}
,
new Online_video_for_programmers
{
video_name="Yoga for programmers",
season=4,
seasontype=2,
year=2011,
},
new Online_video_for_programmers
{
video_name="Yoga for programmers",
season=2,
seasontype=2,
year=2011
}
};
}
// Define other methods and classes here
public class Online_video_for_programmers
{
public int seasontype {get;set;} //this can be the id of a year, a quater or month Tyepes are 1: months, 2, for quarters, 3 for year
public int season {get;set;} // when season type is 1, season =1 means january.
//When season type is 2, season=3 means 3rd quater. When seasontype is 3, season =2011 or 2010 etc...
public string video_name {get;set;} //The nambe of the video
public int year {get;set;} // The year the video was published
}
我想用current_year_videos和last_year_videos来检索去年出版的标题,而不是今年出版的标题。为此,我使用以下代码:
var result=current_year_videos.Concat(last_year_videos).GroupBy( g=> new { seasontype,season,video_name }).Select(s=> new Online_video_for_programmers{ seasontype=s.Key.seasontype, season=s.Key.season, video_name=s.Key.video_name });
上面的代码为我提供了今年和去年生成的代码,以便我可以轻松找到缺少的代码。
这就是问题所在。视频"自我意识机器人的人工智能"在2011年全年制作,而2012年有3个月制作。我不希望看到这在2012年缺失。只有在 2012 年根本没有生产时,它才会丢失。问题是,如何调整我的查询以将此条件包含在结果中。我花了一些时间弄清楚不同的事情,但到目前为止还没有成功。
希望有人能帮忙。
提前非常感谢
var result =
last_year_videos
.Select(v => new { v.video_name, v.season })
.Except(current_year_videos.Select(v => new { v.video_name, v.season }));
给:
{ video_name = "Artificial intelligence for self aware robots", season = 2011 }
{ video_name = "Yoga for programmers", season = 4 }
更新:如果要在检查视频时处理季节类型(月,季度,年),则可以创建将季节和季节类型转换为月份列表的方法:
private static IEnumerable<int> GetMonths(Online_video_for_programmers video)
{
switch (video.seasontype)
{
case 1: return Enumerable.Range(video.season, 1);
case 2: return Enumerable.Range((video.season - 1) * 3 + 1, 3);
case 3: return Enumerable.Range(1, 12);
default:
throw new ArgumentException("Unknown season type");
}
}
使用此方法,您可以检查视频是否与当前年份的相同视频有月份交集:
var currentVideos =
current_year_videos.Select(c => new { c.video_name, months = GetMonths(c) });
var result = from v in last_year_videos
let months = GetMonths(v)
where !currentVideos.Any(cv =>
cv.video_name == v.video_name &&
months.Intersect(cv.months).Any())
select v.video_name;
返回:
"cross site scripting for facebook addicts" // Month 3
"Yoga for programmers" // Months 9,10,11
你想找:
去年出版了哪些标题,今年没有出版
但为此,不需要分组:
var result = last_year_videos
.Where(vLast => !current_year_videos
.Select(vCurrent => vCurrent.video_name).Contains(vLast.video_name));
您所要做的就是检查带有所选键的视频( video_name
)是否存在于去年的收藏中。