2017-07-25 59 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) 
     });