循环遍历多个列表并保存到新列表

本文关键字:列表 新列表 遍历 循环 保存 | 更新日期: 2023-09-27 18:03:04

我有x个客户。对于每个客户,我调用一个数据库,返回一个List<DateTime>
每个列表可以为空或包含x个日期。

我想要实现的是,对于每个客户,我取列表中的第一个日期(最老的),计算该日期在列表中的次数,然后将该数字保存到新的List<int> RegList

每个客户的第一个日期成为RegList中的第一个项目,第二个日期成为第二个项目,以此类推。

列出客户1
{2016-02-19 00:00:00, 2016-02-19 00:00:00}

RegList现在应该是:{2}

列出客户二
{2016-04-22 00:00:00, 2016-04-22 00:00:00, 2016-04-22 00:00:00, 2016-04-25 00:00:00, 2016-04-26 00:00:00, 2016-04-26 00:00:00, 2016-05-02 00:00:00, 2016-05-10 00:00:00}

RegList现在应该是:{2 + 3,1、2、1、1}={5、1、2、1、1}

在第一个客户之后,我的RegList看起来正确:{2}。在第二个客户之后,我的RegList看起来像这样:{5,3,4,3,3,2},这是错误的。我该怎么做呢?

EDIT:日期不重要。任何客户的第一个日期都应该添加到Reglist的第一个项目中,即使日期不同。

private void CalculateRegs(List<DateTime> eventList)
{            
   int num = 0;           
   int i = 0;
   var distinctList = eventList.Distinct().ToList();
   foreach (var date in distinctList)
   {
      num = eventList.Where(x => x.Equals(date)).Count();
      if (RegsList.Count() <= i)
         {
            RegsList.Add(num);
         }
         else
         {
            var tempNum = num + RegsList.ElementAt(i);
            RegsList.Insert(i, tempNum);
         }
         i++;
     }          
  }

循环遍历多个列表并保存到新列表

也许直接将所有日期导入到列表中,然后再进行处理会更容易一些。

像这样;

//Create a list of all the dates from your customers
var dates = new List<DateTime>();
foreach(var customer in Customers)
{
    List<DateTime> customerDates = database.GetDates(customer);
    dates.AddRange(customerDates);
}
//You can either just take the count of all the dates
List<int> RegsList = new List<int>();
var group = dates.GroupBy(d => d)
                 .Select(group => group.Count());
RegsList.AddRange(group);
//Or put them in some other collection to know which date has which count
//for example, a Dictionary
Dictionary<DateTime, int> OtherRegsList = new Dictionary<DateTime, int>();
var group2 = dates.GroupBy(d => d)
                 .Select(group => new { Date = group.Key, Count = group.Count() });
foreach(var g in group2)
{
    OtherRegsList.Add(g.Date, g.Count);
}

(考虑做这个数据库端)

void Main()
{
    List<Customer> customers = new List<Customer> {
       new Customer { 
            CustomerId=1,
            Events = new List<Event> {
                new Event {EventId=1, CustomerId=1, EventDate=new DateTime(2016,2,19)},
                new Event {EventId=2, CustomerId=1, EventDate=new DateTime(2016,2,19)},
            }
        },
        new Customer { 
            CustomerId = 2,
            Events = new List<Event> {
                new Event {EventId=6, CustomerId=2, EventDate=new DateTime(2016,4,25)},
                new Event {EventId=7, CustomerId=2, EventDate=new DateTime(2016,4,25)},
                new Event {EventId=3, CustomerId=2, EventDate=new DateTime(2016,4,22)},
                new Event {EventId=4, CustomerId=2, EventDate=new DateTime(2016,4,22)},
                new Event {EventId=5, CustomerId=2, EventDate=new DateTime(2016,4,22)},
                new Event {EventId=8, CustomerId=2, EventDate=new DateTime(2016,4,26)},
                new Event {EventId=8, CustomerId=2, EventDate=new DateTime(2016,4,26)},
            }
        },
    };
    var counts = from c in customers
                 select new {
                     c.CustomerId,
                     Counts = c.Events
                        .GroupBy(e => e.EventDate)
                        .Select(e => new {Date= e.Key,Count= e.Count()})
                        .OrderBy(e => e.Date)
                 };
}
public class Customer
{
    public int CustomerId { get; set; }
    public virtual List<Event> Events {get;set;}
}
public class Event
{
    public int EventId {get;set;}
    public DateTime EventDate { get; set; }
    public int CustomerId { get; set; }
}

通过查看第二次列表迭代后您期望从数据中获得的值,即{5,1,2,1,1},看起来您想要为每个客户日期列表添加日期出现的次数。有一件事看起来不太对,那就是你用insert来替换

RegsList.Insert(i, tempNum);

这是错误的,因为它只是将前一个值推到下一个索引。试着用下面这行替换上面提到的行:

RegsList[i] = tempNum;

变化

 RegsList.Insert(i, tempNum);

RegsList[i] = tempNum;

您可以使用groupby

将其重写为两个不同的步骤
  private void CalculateRegs(List<DateTime> eventList)
        {
            Dictionary<DateTime, int> counts = eventList.GroupBy(x => x)
                 .ToDictionary(g => g.Key, g => g.Count());
            // merge with reglist
            for (int i = 0; i < counts.Count; i++)
            {
                var el = counts.ElementAt(i);
                if (RegsList.Count <= i)
                {
                    RegsList.Add(counts.ElementAt(i).Value);
                }
                else
                {
                    var tempNum = el.Value + RegsList.ElementAt(i);
                    RegsList[i] = tempNum;
                }
            } 
        }