循环遍历多个列表并保存到新列表
本文关键字:列表 新列表 遍历 循环 保存 | 更新日期: 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;
}
}
}