【问题标题】:advanced grouping and aggregation with linq使用 linq 进行高级分组和聚合
【发布时间】:2013-10-24 09:56:41
【问题描述】:

我有以下程序:

 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 年根本没有产生它时才应该缺失它。问题是,如何调整我的查询以在结果中包含此条件。 到目前为止,我花了一些时间想出不同的东西,但没有成功。

希望有人能提供帮助。

在此先感谢

【问题讨论】:

    标签: c# linq group-by


    【解决方案1】:
    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
    

    【讨论】:

    • 亲爱的 Lazyberezovsky,此代码存在问题。它不应将“具有自我意识的机器人的人工智能”报告为缺失。它是 2011 年生产的。只有在根本没有生产的情况下才应报告为丢失。
    • @MeelfanBmfp 不,2012 年有四季1,3,5。但是在 2011 年是名为2011 的季节,因此它是不同的视频,它会显示在结果中。也许您的示例数据中有错字?
    • 不,我没有解释得那么好。如果我们在一端找到全年的数据,而在另一端找到任何其他形式的数据,则认为它没有丢失。 2011年制作了一次《人工智能的自知机器人》,全年制作一次。 2012年,它按月制作。所以在这里我们可以假设它没有丢失。我希望这是有道理的。
    • “人工智能的自知机器人”诞生于 2011 年,涵盖任何月份或任何季度的全年。因此,这部电影从那一年就没有缺席。如果是生产的,比如:2011 年的 1 月和 4 月,2012 年的 5 月和 6 月,那么我们会将 2011 年的 5 月和 6 月标记为缺失,因为这几个月没有制作电影。反过来,如果在 2011 年,它是在 2 季度(包括 5 月和 6 月)生产的,那么这些生产不会被标记为缺失。我们有 2011 年和 5 月和 6 月的第二季度
    • 没错!你的代码和想法很棒,你是一个真正的天才。我从来没有想过转换的想法。万分感谢
    【解决方案2】:

    你想找的:

    去年和今年没有出版的书名

    但为此,不需要分组:

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

    您所要做的就是检查带有所选密钥 (video_name) 的视频是否存在于去年的收藏中。

    【讨论】:

    • 检查名称。都存在于去年的收藏中
    • 我同意。尽管如此,据我了解,这是解决问题的方法。
    • 即使您将 video_name 替换为匿名对象,您的查询也非常低效 - 它会投影当前年份的视频并执行列表年份列表中的 每个 视频的搜索。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    • 2019-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多