计算从以前项目的差异在一组与(单)的LINQ查询 [英] Calculate difference from previous item in a group with (single) LINQ query

查看:88
本文介绍了计算从以前项目的差异在一组与(单)的LINQ查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想弄清楚如何从以前的项目计算的区别,当需要将数据进行分组。



我有这样

 城区日期公民$ B数据$ b纽约1 2010.11.20 5 
纽约1 2010.11.21 8
纽约1 2010.11.22 12
纽约1 2010.11.23 17
纽约1 2010.11 0.24 23
纽约1 2010.11.25 29

芝加哥1 2010.11.20 5
芝加哥1 2010.11.21 10
芝加哥1 2010.11.22 15
芝加哥1 2010.11.23 20
芝加哥1 2010.11.24 25
芝加哥1 2010.11.25 30

纽约2 2010.11.20 6
纽约2 2010.11.21 7
纽约2 2010.11.22 9
纽约2 2010.11.23 7
纽约2 2010.11.24 10
纽约2 2010.11.25 15

芝加哥2 2010.11.20 5
芝加哥2 2010.11.21 15
芝加哥2 2010.11.22 25
芝加哥2 2010.11.23 20
芝加哥2 2010.11。 24 25
芝加哥2 2010.11.25 30

和我需要添加一列增加每一个都是每个城市,这将减去先前的公民从目前的统计计算。

 预期的结果是这样的

城区日期市民增加
纽约1 2010.11.20 5
纽约1 2010.11.21 8 3
纽约1 2010.11.22 12 $ 4 b $ b纽约1 2010.11.23 17 5
纽约1 2010.11.24 23 6
纽约1 2010.11.25 29 7

芝加哥1 2010.11.20 5
芝加哥1 2010.11.21 10 5
芝加哥1 2010.11.22 15 5
芝加哥1 2010.11.23 20 5
芝加哥1 2010.11.24 25 5
芝加哥1 2010.11.25 30 5

纽约2 2010.11.20 6 6
纽约2 2010.11.21 7 1
纽约2 2010.11.22 9 2
新纽约2 2010.11.23 7 -2
纽约2 2010.11.24 10 3
纽约2 2010.11.25 15 5

芝加哥2 2010.11.20 5
芝加哥2 2010.11.21 15 10
芝加哥2 2010.11.22 25 10
芝加哥2 2010.11.23 20 -5
芝加哥2 2010.11.24 25 5
芝加哥2 2010.11。 25 30 5

我不知道这是否可以用一个单一的LINQ查询来完成,避免了
的foreach(城市三)
的foreach(一个区)
....



的问题是如何计算线7 在这里根本差异,以此前的纪录是-24,就当是应该是5



下面是一个示例代码:

 使用系统; 
使用System.Collections.Generic;

命名ConsoleApplication1
{
公共类MyObject的
{
公众诠释ID {搞定;组; }
公共字符串城{获取;设置; }
公众的DateTime日期{搞定;组; }
公共int值{搞定;组; }
公众诠释DiffToPrev {搞定;组; }
}

类节目
{

静态无效的主要()
{
无功名单=新名单,LT;为MyObject> ;
{
新MyObject的{ID = 1,城市=纽约,日期= DateTime.Now,值= 5}
新MyObject的{ID = 1,城市=纽约日期= DateTime.Now.AddDays(1),值= 8}
新MyObject的{ID = 1,城市=纽约,日期= DateTime.Now.AddDays(2),值= 12 }
新MyObject的{ID = 1,城市=纽约,日期= DateTime.Now.AddDays(3),值= 17},
新MyObject的{ID = 1,城市=纽约,日期= DateTime.Now.AddDays(4),值= 23}
新MyObject的{ID = 1,城市=纽约,日期= DateTime.Now.AddDays(5),值= 29}

新MyObject的{ID = 1,市=芝加哥,日期= DateTime.Now,值= 5}
新MyObject的{ID = 1,城市=芝加哥,日期= DateTime.Now.AddDays(1),值= 10}
新MyObject的{ID = 1,市=芝加哥,日期= DateTime.Now.AddDays(2),值= 15 }
新MyObject的{ID = 1,市=芝加哥,日期= DateTime.Now.AddDays(3),值= 20}
新MyObject的{ID = 1,市=芝加哥日期= DateTime.Now.AddDays(4),值= 25}
新MyObject的{ID = 1,市=芝加哥,日期= DateTime.Now.AddDays(5),值= 30} ,

新MyObject的{ID = 2,市=纽约,日期= DateTime.Now,值= 6}
新MyObject的{ID = 2,市=纽约日期= DateTime.Now.AddDays(1),值= 7}
新MyObject的{ID = 2,市=纽约,日期= DateTime.Now.AddDays(2),值= 9 }
新MyObject的{ID = 2,市=纽约,日期= DateTime.Now.AddDays(3)值= 7}
新MyObject的{ID = 2,市=纽约,日期= DateTime.Now.AddDays(4),值= 10}
新MyObject的{ID = 2,市=纽约,日期= DateTime.Now.AddDays(5),值= 15}

新MyObject的{ID = 2,市=芝加哥,日期= DateTime.Now,值= 5}
新MyObject的{ID = 2,市=芝加哥,日期= DateTime.Now.AddDays(1),值= 15}
新MyObject的{ID = 2,市=芝加哥,日期= DateTime.Now.AddDays(2),值= 25 }
新MyObject的{ID = 2,市=芝加哥,日期= DateTime.Now.AddDays(3),值= 20}
新MyObject的{ID = 2,市=芝加哥日期= DateTime.Now.AddDays(4),值= 25}
新MyObject的{ID = 2,市=芝加哥,日期= DateTime.Now.AddDays(5),值= 30} ,
};

}
}
}


解决方案

您可以这样做:

  VAR newList = list.GroupBy(X =>新{x.City,x.ID})
。选择

X =>
{
无功子列表= x.OrderBy(Y => Y .Date).ToList();
返回subList.Select((Y,IDX)=>新建MyObject的
{
ID = y.ID,
市= Y。市,
日期= y.Date,
值= y.Value,
DiffToPrev =(IDX == 0)y.Value:y.Value - subList.ElementAt(IDX-1 ).value的
});
}

.SelectMany(X => X)
.ToList();






无论如何,我认为在这种情况下foreach语句更清晰(而不是更长),例如:

 列表<&MyObject的GT; newList =新的List<&MyObject的GT;(); 
的foreach(在list.GroupBy VAR GRP(X =>新建{x.City,x.ID}))
{
MyObject来前页= NULL;
的foreach(在grp.OrderBy VAR OBJ(Y => y.Date))
{
newList.Add(新MyObject的
{
ID = OBJ。 ID,
市= obj.City,
日期= obj.Date,
值= obj.Value,
DiffToPrev =(前== NULL)obj.Value:OBJ .value的 - prev.Value
});
=上一个OBJ;
}
}



PS 结果
显然在foreach代码(根据您的需要),您可以设置 DiffToPrev 直接在现有对象上( OBJ ),而不是创建一个新的,因此可选的 newList 。






结果:

  ID:1,城市:纽约,日期:21/11/2010 12:52:40,值:5,DIFF:5 
ID:1,城市:纽约,日期:22/11/2010 12:52:40,值:8,DIFF :3
ID:1,城市:纽约,日期:23/11/2010 12:52:40,值:12,DIFF:4
ID:1,城市:纽约,日期: 24/11/2010 12:52:40,值:17,DIFF:5
ID:1,城市:纽约,日期:25/11/2010 12:52:40,值:23,DIFF: 6
ID:1,城市:纽约,日期:26/11/2010 12:52:40,值:29,DIFF:6
ID:1,城市:芝加哥,日期:21 / 11/2010 12:52:40,值:5,DIFF:5
ID:1,城市:芝加哥,日期:22/11/2010 12:52:40,值:10,DIFF:5
ID:1,城市:芝加哥,日期:23/11/2010 12:52:40,值:15,DIFF:5
ID:1,城市:芝加哥,日期:24/11/2010 12 :52:40,值:20,DIFF:5
ID:1,城市:芝加哥,日期:25/11/2010 12:52:40,值:25,DIFF:5
ID: 1,城市:芝加哥,日期:26/11/2010 12:52:40,值:30,DIFF:5
编号:2,城市:纽约,日期:21/11/2010 12:52: 40,值:6,DIFF:6
编号:2,城市:纽约,日期:22/11/2010 12:52:40,值:7,DIFF:1
编号:2,城市:纽约,日期:23/11/2010 12:52:40,值:9,DIFF:2
编号:2,城市:纽约,日期:24/11/2010十二时52分四十秒,值:7,DIFF:-2
编号:2,城市:纽约,日期:25/11/2010 12:52:40,值:10,DIFF:3
编号:2,城市:纽约,日期:26/11/2010 12:52:40,值:15,DIFF:5
编号:2,城市:芝加哥,日期:21/11/2010十二点52分40秒,值:5,DIFF:5
编号:2,城市:芝加哥,日期:22/11/2010 12:52:40,值:15,DIFF:10
编号:2,城市:芝加哥,日期:23/11/2010 12:52:40,值:25,DIFF:10
编号:2,城市:芝加哥,日期:24/11/2010 12:52:40,值:20, DIFF:-5
编号:2,城市:芝加哥,日期:25/11/2010 12:52:40,值:25,DIFF:5
编号:2,城市:芝加哥,日期: 26/11/2010 12:52:40,值:30,DIFF:5
ID:1,城市:纽约,日期:21/11/2010 12:52:40,值:5,DIFF: 5
ID:1,城市:纽约,日期:22/11/2010 12:52:40,值:8,DIFF:3
ID:1,城市:纽约,日期:23 / 11/2010 12:52:40,值:12,DIFF:4
ID:1,城市:纽约,日期:24/11/2010 12:52:40,值:17,DIFF:5
ID:1,城市:纽约,日期:25/11/2010 12:52:40,值:23,DIFF:6
ID:1,城市:纽约,日期:26 / 11/2010 12:52:40,值:29,DIFF:6
ID:1,城市:芝加哥,日期:21/11/2010 12:52:40,值:5,DIFF:5
ID:1,城市:芝加哥,日期:22/11/2010 12:52:40,值:10,DIFF:5
ID:1,城市:芝加哥,日期:23/11/2010 12 :52:40,值:15,DIFF:5
ID:1,城市:芝加哥,日期:24/11/2010 12:52:40,值:20,DIFF:5
ID: 1,城市:芝加哥,日期:25/11/2010 12:52:40,值:25,DIFF:5
ID:1,城市:芝加哥,日期:26/11/2010 12点52分40秒,值:30,DIFF:5
编号:2,城市:纽约,日期:21/11/2010 12:52:40,值:6,DIFF:6
编号:2,市:纽约,日期:22/11/2010 12:52:40,值:7,DIFF:1
编号:2,城市:纽约,日期:23/11/2010十二点52分四十秒,值:9,DIFF:2
编号:2,城市:纽约,日期:24/11/2010 12:52:40,值:7,DIFF:-2
编号:2,市:纽约,日期:25/11/2010 12:52:40,值:10,DIFF:3
编号:2,城市:纽约,日期:26/11/2010 12时52分四十秒,值:15,DIFF:5
编号:2,城市:芝加哥,日期:21/11/2010 12:52:40,值:5,DIFF:5
编号:2,城市:芝加哥,日期:22/11/2010 12:52:40,值:15,DIFF:10
编号:2,城市:芝加哥,日期:23/11/2010 12:52:40,值:25, DIFF:10
编号:2,城市:芝加哥,日期:24/11/2010 12:52:40,值:20,DIFF:-5
编号:2,城市:芝加哥,日期: 25/11/2010 12:52:40,值:25,DIFF:5
编号:2,城市:芝加哥,日期:26/11/2010 12:52:40,值:30,DIFF:5


I'm trying to figure out how to calculate difference from previous item, when the data needs to be grouped.

I have data like this

City      Area  Date        Citizens
New York    1   2010.11.20  5
New York    1   2010.11.21  8
New York    1   2010.11.22  12
New York    1   2010.11.23  17
New York    1   2010.11.24  23
New York    1   2010.11.25  29

Chicago 1   2010.11.20  5
Chicago 1   2010.11.21  10
Chicago 1   2010.11.22  15
Chicago 1   2010.11.23  20
Chicago 1   2010.11.24  25
Chicago 1   2010.11.25  30

New York    2   2010.11.20  6
New York    2   2010.11.21  7
New York    2   2010.11.22  9
New York    2   2010.11.23  7
New York    2   2010.11.24  10
New York    2   2010.11.25  15

Chicago 2   2010.11.20  5
Chicago 2   2010.11.21  15
Chicago 2   2010.11.22  25
Chicago 2   2010.11.23  20
Chicago 2   2010.11.24  25
Chicago 2   2010.11.25  30

and I need to add a column "Increase" for each are for each city, which would be calculated by subtracting previous Citizens count from current.

The expected result is like this

City    Area    Date    Citizens    Increase
New York    1   2010.11.20  5   5
New York    1   2010.11.21  8   3
New York    1   2010.11.22  12  4
New York    1   2010.11.23  17  5
New York    1   2010.11.24  23  6
New York    1   2010.11.25  29  7

Chicago 1   2010.11.20  5   5
Chicago 1   2010.11.21  10  5
Chicago 1   2010.11.22  15  5
Chicago 1   2010.11.23  20  5
Chicago 1   2010.11.24  25  5
Chicago 1   2010.11.25  30  5

New York    2   2010.11.20  6   6
New York    2   2010.11.21  7   1
New York    2   2010.11.22  9   2
New York    2   2010.11.23  7   -2
New York    2   2010.11.24  10  3
New York    2   2010.11.25  15  5

Chicago 2   2010.11.20  5   5
Chicago 2   2010.11.21  15  10
Chicago 2   2010.11.22  25  10
Chicago 2   2010.11.23  20  -5
Chicago 2   2010.11.24  25  5
Chicago 2   2010.11.25  30  5

I wonder if this can be done with a single linq query, avoiding "foreach (c in cities) foreach (a in area) ...."

The problem is how to calculate line "7" where simply diff to previous record would be -24, when is should be 5.

Here's a sample code :

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    public class MyObject
    {
        public int ID { get; set; }
        public string City { get;set; }
        public DateTime Date { get; set; }
        public int Value { get; set; }
        public int DiffToPrev { get; set; }
    }

    class Program
    {

        static void Main()
        {
            var list = new List<MyObject>
              {
                new MyObject {ID= 1, City = "New York",Date = DateTime.Now,          Value = 5},
                new MyObject {ID= 1, City = "New York",Date = DateTime.Now.AddDays(1),Value = 8},
                new MyObject {ID= 1, City = "New York",Date = DateTime.Now.AddDays(2),Value = 12},
                new MyObject {ID= 1, City = "New York",Date = DateTime.Now.AddDays(3),Value = 17},
                new MyObject {ID= 1, City = "New York",Date = DateTime.Now.AddDays(4),Value = 23},
                new MyObject {ID= 1, City = "New York",Date = DateTime.Now.AddDays(5),Value = 29},

                new MyObject {ID= 1, City = "Chicago",Date = DateTime.Now,           Value = 5},
                new MyObject {ID= 1, City = "Chicago",Date = DateTime.Now.AddDays(1),Value = 10},
                new MyObject {ID= 1, City = "Chicago",Date = DateTime.Now.AddDays(2),Value = 15},
                new MyObject {ID= 1, City = "Chicago",Date = DateTime.Now.AddDays(3),Value = 20},
                new MyObject {ID= 1, City = "Chicago",Date = DateTime.Now.AddDays(4),Value = 25},
                new MyObject {ID= 1, City = "Chicago",Date = DateTime.Now.AddDays(5),Value = 30},

                new MyObject {ID= 2, City = "New York",Date = DateTime.Now,          Value = 6},
                new MyObject {ID= 2, City = "New York",Date = DateTime.Now.AddDays(1),Value = 7},
                new MyObject {ID= 2, City = "New York",Date = DateTime.Now.AddDays(2),Value = 9},
                new MyObject {ID= 2, City = "New York",Date = DateTime.Now.AddDays(3),Value = 7},
                new MyObject {ID= 2, City = "New York",Date = DateTime.Now.AddDays(4),Value = 10},
                new MyObject {ID= 2, City = "New York",Date = DateTime.Now.AddDays(5),Value = 15},

                new MyObject {ID= 2, City = "Chicago",Date = DateTime.Now,           Value = 5},
                new MyObject {ID= 2, City = "Chicago",Date = DateTime.Now.AddDays(1),Value = 15},
                new MyObject {ID= 2, City = "Chicago",Date = DateTime.Now.AddDays(2),Value = 25},
                new MyObject {ID= 2, City = "Chicago",Date = DateTime.Now.AddDays(3),Value = 20},
                new MyObject {ID= 2, City = "Chicago",Date = DateTime.Now.AddDays(4),Value = 25},
                new MyObject {ID= 2, City = "Chicago",Date = DateTime.Now.AddDays(5),Value = 30},               
            };

        }
    }
}

解决方案

You can do in this way:

var newList = list.GroupBy(x => new { x.City, x.ID })
.Select
(
    x =>
    {
        var subList = x.OrderBy(y => y.Date).ToList();
        return subList.Select((y, idx) => new MyObject
        {
            ID = y.ID,
            City = y.City,
            Date = y.Date,
            Value = y.Value,
            DiffToPrev = (idx == 0) ? y.Value : y.Value - subList.ElementAt(idx-1).Value 
        });
    }
)
.SelectMany(x => x)
.ToList();


Anyway, I think in this case a foreach statement is clearer (and not longer), e.g.:

List<MyObject> newList = new List<MyObject>();
foreach (var grp in list.GroupBy(x => new { x.City, x.ID }))
{
    MyObject prev = null;
    foreach (var obj in grp.OrderBy(y => y.Date))
    {
        newList.Add(new MyObject
        {
            ID = obj.ID,
            City = obj.City,
            Date = obj.Date,
            Value = obj.Value,
            DiffToPrev = (prev == null) ? obj.Value : obj.Value - prev.Value
        });
        prev = obj;
    }
}

P.S.
obviously (depending on your needs) in the foreach code you can set the DiffToPrev directly on the existing object (obj) instead of creating a new one, making optional the creation of newList.


Results:

ID: 1,City: New York,Date: 21/11/2010 12:52:40,Value: 5,Diff: 5
ID: 1,City: New York,Date: 22/11/2010 12:52:40,Value: 8,Diff: 3
ID: 1,City: New York,Date: 23/11/2010 12:52:40,Value: 12,Diff: 4
ID: 1,City: New York,Date: 24/11/2010 12:52:40,Value: 17,Diff: 5
ID: 1,City: New York,Date: 25/11/2010 12:52:40,Value: 23,Diff: 6
ID: 1,City: New York,Date: 26/11/2010 12:52:40,Value: 29,Diff: 6
ID: 1,City: Chicago,Date: 21/11/2010 12:52:40,Value: 5,Diff: 5
ID: 1,City: Chicago,Date: 22/11/2010 12:52:40,Value: 10,Diff: 5
ID: 1,City: Chicago,Date: 23/11/2010 12:52:40,Value: 15,Diff: 5
ID: 1,City: Chicago,Date: 24/11/2010 12:52:40,Value: 20,Diff: 5
ID: 1,City: Chicago,Date: 25/11/2010 12:52:40,Value: 25,Diff: 5
ID: 1,City: Chicago,Date: 26/11/2010 12:52:40,Value: 30,Diff: 5
ID: 2,City: New York,Date: 21/11/2010 12:52:40,Value: 6,Diff: 6
ID: 2,City: New York,Date: 22/11/2010 12:52:40,Value: 7,Diff: 1
ID: 2,City: New York,Date: 23/11/2010 12:52:40,Value: 9,Diff: 2
ID: 2,City: New York,Date: 24/11/2010 12:52:40,Value: 7,Diff: -2
ID: 2,City: New York,Date: 25/11/2010 12:52:40,Value: 10,Diff: 3
ID: 2,City: New York,Date: 26/11/2010 12:52:40,Value: 15,Diff: 5
ID: 2,City: Chicago,Date: 21/11/2010 12:52:40,Value: 5,Diff: 5
ID: 2,City: Chicago,Date: 22/11/2010 12:52:40,Value: 15,Diff: 10
ID: 2,City: Chicago,Date: 23/11/2010 12:52:40,Value: 25,Diff: 10
ID: 2,City: Chicago,Date: 24/11/2010 12:52:40,Value: 20,Diff: -5
ID: 2,City: Chicago,Date: 25/11/2010 12:52:40,Value: 25,Diff: 5
ID: 2,City: Chicago,Date: 26/11/2010 12:52:40,Value: 30,Diff: 5
ID: 1,City: New York,Date: 21/11/2010 12:52:40,Value: 5,Diff: 5
ID: 1,City: New York,Date: 22/11/2010 12:52:40,Value: 8,Diff: 3
ID: 1,City: New York,Date: 23/11/2010 12:52:40,Value: 12,Diff: 4
ID: 1,City: New York,Date: 24/11/2010 12:52:40,Value: 17,Diff: 5
ID: 1,City: New York,Date: 25/11/2010 12:52:40,Value: 23,Diff: 6
ID: 1,City: New York,Date: 26/11/2010 12:52:40,Value: 29,Diff: 6
ID: 1,City: Chicago,Date: 21/11/2010 12:52:40,Value: 5,Diff: 5
ID: 1,City: Chicago,Date: 22/11/2010 12:52:40,Value: 10,Diff: 5
ID: 1,City: Chicago,Date: 23/11/2010 12:52:40,Value: 15,Diff: 5
ID: 1,City: Chicago,Date: 24/11/2010 12:52:40,Value: 20,Diff: 5
ID: 1,City: Chicago,Date: 25/11/2010 12:52:40,Value: 25,Diff: 5
ID: 1,City: Chicago,Date: 26/11/2010 12:52:40,Value: 30,Diff: 5
ID: 2,City: New York,Date: 21/11/2010 12:52:40,Value: 6,Diff: 6
ID: 2,City: New York,Date: 22/11/2010 12:52:40,Value: 7,Diff: 1
ID: 2,City: New York,Date: 23/11/2010 12:52:40,Value: 9,Diff: 2
ID: 2,City: New York,Date: 24/11/2010 12:52:40,Value: 7,Diff: -2
ID: 2,City: New York,Date: 25/11/2010 12:52:40,Value: 10,Diff: 3
ID: 2,City: New York,Date: 26/11/2010 12:52:40,Value: 15,Diff: 5
ID: 2,City: Chicago,Date: 21/11/2010 12:52:40,Value: 5,Diff: 5
ID: 2,City: Chicago,Date: 22/11/2010 12:52:40,Value: 15,Diff: 10
ID: 2,City: Chicago,Date: 23/11/2010 12:52:40,Value: 25,Diff: 10
ID: 2,City: Chicago,Date: 24/11/2010 12:52:40,Value: 20,Diff: -5
ID: 2,City: Chicago,Date: 25/11/2010 12:52:40,Value: 25,Diff: 5
ID: 2,City: Chicago,Date: 26/11/2010 12:52:40,Value: 30,Diff: 5

这篇关于计算从以前项目的差异在一组与(单)的LINQ查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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