使用linq进行高级分组和聚合

时间:2013-10-24 09:56:42

标签: c# linq group-by

我有以下程序:

 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年根本没有生成,它应该只是缺失。问题是,如何调整我的查询以在结果中包含这个条件。 到目前为止,我花了一些时间来计算不同的事情并没有成功。

希望有人可以提供帮助。

非常感谢提前

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:0)

你想找到:

  

去年发布的是什么标题,而不是今年

但为此,不需要分组:

var result = last_year_videos
    .Where(vLast => !current_year_videos
        .Select(vCurrent => vCurrent.video_name).Contains(vLast.video_name));

您所要做的就是检查上一年的收藏中是否存在带有所选键(video_name)的视频。