2017-07-25 64 views
2

我有一个对象列表,其中每个对象都有一个字符串和一个int。每个字符串都是yyyy-M-d格式的日期。按日期和C#中的总和值对对象分组

列表可以包含日期30,90或365nm天的第一次约会

左右(30天)的项目清单是:

2017-7-25 10 
2017-7-24 3 
2017-7-23 7 
2017-7-22 4 
2017-7-21 2 
2017-7-20 4 
.. 
2017-6-27 5 
2017-6-26 8 

我希望将这些日期由5天如此:

2017-7-21 30 
2017-7-16 (Sum of values from 7-16 till 7-20) 

等等。

我不能找出这个lambda。

var grouped = from x in list 
       group x by DateTime.Parse(x.date)/5 
       select new { date = x.????????, count = x.Sum()} 
+0

的日子独特? – Christos

+0

@克里斯托斯是的,这些日子是独一无二的。我纠正了我在问题列表中犯的错误。 这个列表基本上是从现在开始每天都会回到30或90或365天,并且每天的值(可以是0) – ArmenHeat

回答

1

如果您已声明类似下面的类:

internal class DayNumber 
{ 
    public string Day { get; set; } 
    public int Number { get; set; } 
} 

,并定义了诸如列表以下之一:

var list = new List<DayNumber> 
{ 
    new DayNumber {Day = "2017-7-25", Number = 10}, 
    new DayNumber {Day = "2017-7-24", Number = 3}, 
    new DayNumber {Day = "2017-7-23", Number = 7}, 
    new DayNumber {Day = "2017-7-22", Number = 4}, 
    new DayNumber {Day = "2017-7-21", Number = 2}, 
    new DayNumber {Day = "2017-7-20", Number = 4}, 
    new DayNumber {Day = "2017-7-19", Number = 5}, 
    new DayNumber {Day = "2017-7-18", Number = 8}, 
    new DayNumber {Day = "2017-7-17", Number = 2}, 
    new DayNumber {Day = "2017-7-16", Number = 3} 
}; 

那么你可以尝试这样的事:

var grouped = list.Select(item => new 
        { 
         Parsed = DateTime.ParseExact(item.Day, "yyyy-M-dd", CultureInfo.InvariantCulture), 
         Number = item.Number 
        }) 
        .OrderBy(item => item.Parsed) 
        .Select((item, index) => new 
        { 
         Index = index, 
         Item = item 
        }) 
        .GroupBy(item => item.Index/5) 
        .Select(gr => new 
        { 
         Date = gr.First().Item.Parsed, 
         Count = gr.Sum(x => x.Item.Number) 
        }) 
        .ToList(); 
+0

据我所知,只有在连续天数的情况下,此功能才有效。 –

-1
  KeyValuePair<string, int> kvp = new KeyValuePair<string, int>(); 
      IList < KeyValuePair < string, int> > list= new 
      List<KeyValuePair<string, int>>(); 

      list.Add(new KeyValuePair<string, int>("2017 - 7 - 25", 10)); 
      list.Add(new KeyValuePair<string, int>("2017 - 7 - 24", 3)); 
      list.Add(new KeyValuePair<string, int>("2017 - 7 - 23", 7)); 
      list.Add(new KeyValuePair<string, int>("2017 - 7 - 22", 4)); 
      list.Add(new KeyValuePair<string, int>("2017 - 7 - 21", 2)); 
      list.Add(new KeyValuePair<string, int>("2017 - 7 - 25", 5)); 
      list.Add(new KeyValuePair<string, int>("2017 - 6 - 26", 8)); 
      list.Add(new KeyValuePair<string, int>("2017 - 5 - 26", 18)); 


      TimeSpan interval = TimeSpan.FromDays(5);  
      var output=list.GroupBy(x => DateTime.Parse(x.Key).Ticks/interval.Ticks) 
      .Select((n) => new { GroupId = new DateTime(n.Key * interval.Ticks), Sum= n.Sum(x => x.Value) }) 
1

这将工作,无论日期的唯一性和日期之间的差距。


假设我们有类代表对象

public class MyClass 
{ 
    public string DateString { get; set; } 

    public int SomeInt { get; set; } 
} 

那么我们的这个对象数组

MyClass[] array = new[] 
{ 
    new MyClass { DateString = "2017-7-25", SomeInt = 10 }, 
    new MyClass { DateString = "2017-7-24", SomeInt = 3 }, 
    new MyClass { DateString = "2017-7-23", SomeInt = 7 }, 
    new MyClass { DateString = "2017-7-22", SomeInt = 4 }, 
    new MyClass { DateString = "2017-7-21", SomeInt = 2 }, 
    new MyClass { DateString = "2017-7-20", SomeInt = 4 }, 
    new MyClass { DateString = "2017-7-25", SomeInt = 5 }, 
    new MyClass { DateString = "2017-6-26", SomeInt = 8 } 
}; 

在这种情况下,代码将

// get object array with parsed dates 
var arrayWithDates = array.Select(el => 
    new 
    { 
     Date = DateTime.ParseExact(el.DateString, "yyyy-M-d", CultureInfo.InvariantCulture), 
     SomeInt = el.SomeInt 
    }); 

// get minimum date 
DateTime minDate = arrayWithDates.Min(el => el.Date); 

// get maximum date 
DateTime maxDate = arrayWithDates.Max(el => el.Date); 

// get total days 
int days = (maxDate - minDate).Days; 

// getting all dates from minDate to maxDate 
IEnumerable<DateTime> dateRange = Enumerable.Range(0, days + 1) 
    .Select(el => minDate.AddDays(el)); 

// split all dates into groups of 5 dates 
IEnumerable<DateTime[]> groupedDateRanges = dateRange 
    .Select((el, index) => new { el.Date, index }) 
    .GroupBy(el => el.index/5) 
    .Select(g => g.Select(el => el.Date).ToArray()); 

var results = groupedDateRanges 
    // getting list of object within each range 
    .Select(groupedDateRange => arrayWithDates.Where(el => groupedDateRange.Contains(el.Date))) 
    // selecting minimum date of range, maximum date of range and sum by int value 
    .Select(item => 
     new 
     { 
      MinDate = item.Min(el => el.Date), 
      MaxDate = item.Max(el => el.Date), 
      Sum = item.Sum(el => el.SomeInt) 
     });