如何优化linq查询以按价格对日期进行分组而不合并结果 [英] How to optmize linq query for grouping dates by price without merging results

查看:145
本文介绍了如何优化linq查询以按价格对日期进行分组而不合并结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个linq查询如下所述。问题是当数据按价格分组时,它将按日期分组,而不考虑非连续日期可能出现相同价格的情况。 c>使用系统;
使用System.Collections.Generic;
使用System.Linq;

public class Program
{
public static void Main()
{
//Console.WriteLine(\"Hello World);
列表<价格> list = new List< Prices>();
list.Add(new Prices(){Date = DateTime.Parse(2017-06-17),Price = Double.Parse(50)});
list.Add(new Prices(){Date = DateTime.Parse(2017-06-18),Price = Double.Parse(50)});
list.Add(new Prices(){Date = DateTime.Parse(2017-06-19),Price = Double.Parse(50)});
list.Add(new Prices(){Date = DateTime.Parse(2017-06-20),Price = Double.Parse(100)});
list.Add(new Prices(){Date = DateTime.Parse(2017-06-21),Price = Double.Parse(100)});
list.Add(new Prices(){Date = DateTime.Parse(2017-06-22),Price = Double.Parse(100)});
list.Add(new Prices(){Date = DateTime.Parse(2017-06-23),Price = Double.Parse(50)});
list.Add(new Prices(){Date = DateTime.Parse(2017-06-24),Price = Double.Parse(50)});
list.Add(new Prices(){Date = DateTime.Parse(2017-06-25),Price = Double.Parse(50)});


var baseservices = list
.GroupBy(l => l.Price)
.Select(g => new
{
Price = g.Key,
PeriodStart = g.Select(l => l.Date).Min(),
PeriodEnd = g.Select(l => l.Date)。 Max(),
});

foreach(baseservices中的var item)
{
Console.WriteLine(item.Price ++ item.PeriodStart ++ item.PeriodEnd);




$ b公共类价格
{
public DateTime Date {get; set;}
public double Price {get; set;}
}

public class Quote
{
public DateTime PeriodStart {get; set;}
public DateTime PeriodEnd {get; set;}
public double Price {get; set;}
}

结果是

  50 2017/5/17 12:00:00 AM 6/25/2017 :00:00 AM 
100 6/20/2017 12:00:00 AM 6/22/2017 12:00:00 AM

我如何得到以下结果:

  50 6/17/2017 12: 00:00 AM 6/29/2017 12:00:00 AM 
100 6/20/2017 12:00:00 6/22/2017 12:00:00 AM
50 6/23 / 2017 12:00:00 AM 6/25/2017 12:00:00 AM


解决方案

LINQ不适合这样的操作。唯一可用于执行此类处理的标准LINQ操作符是 Aggregate ,但它不超过LINQ-ish foreach 循环:

  var baseservices = list 
.OrderBy(e => e.Date)
。如果(r.Count> 0& r [r.Count-1] .Price = 1,则集合(新列表< Quote> = e.Price&& r [r.Count - 1] .PeriodEnd.AddDays(1)== e.Date)
r [r.Count - 1] .PeriodEnd = e.Date;
else
r.Add(新报价{Price = e.Price,PeriodStart = e.Date,PeriodEnd = e.Date});
return r;
});

请注意,与许多LINQ方法相反,它会立即执行并且不会返回,直到整个结果为止准备好。


I have this linq query as stated below. The problem is when the data is grouped by price, it groups dates by price without considering a case where same price can occur for nonconsecutive dates

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        //Console.WriteLine("Hello World");
        List<Prices> list = new List<Prices>();
        list.Add(new Prices() { Date = DateTime.Parse("2017-06-17"), Price = Double.Parse("50")});
        list.Add(new Prices() { Date = DateTime.Parse("2017-06-18"), Price = Double.Parse("50")});
        list.Add(new Prices() { Date = DateTime.Parse("2017-06-19"), Price = Double.Parse("50")});
        list.Add(new Prices() { Date = DateTime.Parse("2017-06-20"), Price = Double.Parse("100")});
        list.Add(new Prices() { Date = DateTime.Parse("2017-06-21"), Price = Double.Parse("100")});
        list.Add(new Prices() { Date = DateTime.Parse("2017-06-22"), Price = Double.Parse("100")});
        list.Add(new Prices() { Date = DateTime.Parse("2017-06-23"), Price = Double.Parse("50")});
        list.Add(new Prices() { Date = DateTime.Parse("2017-06-24"), Price = Double.Parse("50")});
        list.Add(new Prices() { Date = DateTime.Parse("2017-06-25"), Price = Double.Parse("50")});


        var baseservices = list
                .GroupBy(l => l.Price)
                .Select(g => new
                {
                    Price = g.Key,
                    PeriodStart = g.Select(l=>l.Date).Min(),
                    PeriodEnd = g.Select(l => l.Date).Max(),
                });

        foreach(var item in baseservices)
        {
            Console.WriteLine(item.Price + " " + item.PeriodStart + " " + item.PeriodEnd);  
        }

    }
}

public class Prices
{
    public DateTime Date {get;set;}
    public double Price {get;set;}  
}

public class Quote
{
    public DateTime PeriodStart {get;set;}
    public DateTime PeriodEnd {get;set;}
    public double Price {get;set;}  
}

The result is

50 6/17/2017 12:00:00 AM 6/25/2017 12:00:00 AM
100 6/20/2017 12:00:00 AM 6/22/2017 12:00:00 AM

How can I get the following result

50 6/17/2017 12:00:00 AM 6/29/2017 12:00:00 AM
100 6/20/2017 12:00:00 AM 6/22/2017 12:00:00 AM
50 6/23/2017 12:00:00 AM 6/25/2017 12:00:00 AM

解决方案

LINQ is not well suited for such operations. The only standard LINQ operator that can be used to do such processing is Aggregate, but it's no more than LINQ-ish foreach loop:

var baseservices = list
    .OrderBy(e => e.Date)
    .Aggregate(new List<Quote>(), (r, e) =>
    {
        if (r.Count > 0 && r[r.Count - 1].Price == e.Price && r[r.Count - 1].PeriodEnd.AddDays(1) == e.Date)
            r[r.Count - 1].PeriodEnd = e.Date;
        else
            r.Add(new Quote { Price = e.Price, PeriodStart = e.Date, PeriodEnd = e.Date });
        return r;
    });

Note that in contrast with many LINQ methods, this executes immediate and does not return until the whole result is ready.

这篇关于如何优化linq查询以按价格对日期进行分组而不合并结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆