【问题标题】:Why List is not filled with n number of records and x number of dates, 2 differen records per date, until all dates are used? C#为什么 List 没有填充 n 条记录和 x 条日期,每个日期有 2 条不同的记录,直到使用所有日期? C#
【发布时间】:2018-04-09 20:17:22
【问题描述】:
int dateOffset = 0;
DateTimeOffset currentDate = DateTimeOffset.Now;
do
{
    int sameDayCount = 0;
    do
    {
        for (int record = 0; record < List.Count; record++)
        {
            Client client = new Client();
            client.Name = List[record].Name;
            client.Date = currentDate.AddDays(dateOffset);
            List2.Add(client);
            sameDayCount += 1;
        }
    } while (sameDayCount < 2);
    dateOffset += 1;
} while (dateOffset < 30);

以上是我编写的代码,这要归功于我对 C# 语言的了解和经验。 正如您所料,它没有按预期工作。

我需要用来自List 的数据和附加元素 -DateTime 填充List2

基本上我想安排客户的姓名为 30 天,每天两个。

在我写的代码中,我希望do{} while (sameDayCount &lt; 2); 能工作,但sameDayCount += 1;for 循环内,do{} while 实际上等待for 循环完成(当它到达@987654330 @)。无论如何,for 循环将从record = 0 重新开始,我需要它从最后一个点继续下去,当达到每天 2 条记录时。

知道如何解决这个问题吗?

所以有:

具有有限数量记录的列表(客户名称)

30 天与记录一起分配

每个日期必须有两条不同的记录

必须从离开的地方重新读取包含记录的列表

当列表完全迭代(b=List.Count)时,它会从 b=0 重新开始

到第 30 天时,整个循环结束。

简而言之,看到我的问题根本不清楚。 假设第一个列表包含 5 个客户(数量可能会有所不同)。 我想用这 5 个客户 + 7 天填充第二个列表。 我希望第二个列表变成这样:

第 1 天 - 客户 1、客户 2

第 2 天 - 客户 3、客户 4

第 3 天 - 客户 5,客户 1

第 4 天 - 客户 2,客户 3

day5 - client4, client5

第 6 天 - 客户 1、客户 2

第 7 天 - 客户 3、客户 4

【问题讨论】:

  • 您可以在一行中使用 LINQ 轻松完成此操作。
  • 请重命名您的变量,使其不那么神秘。 stb 在现实世界中代表什么?
  • 你能解释一下 maccettura 吗?我听说过 LINQ 并做了一些事情,但我不确定这是否是我认为的那样。
  • @Dai 他们只是循环的辅助号码
  • 我不清楚每天 2 条记录是什么意思。您想每天安排 2 次 cilents 还是每天安排同一客户两次或每天安排所有客户两次?为什么您需要一份副本(如果您想每天安排 2 个客户)?您不能将日期分配给现有列表中的客户吗?

标签: c# list


【解决方案1】:

你可以用一个 for 循环来做到这一点,只需步进 2 步

DateTime currentDate = DateTime.Now.Date;

for (int i = 0; i < List.Count && i < 60; i += 2) {
    AddClient(i, currentDate);
    if (i + 1 < List.Count) {
        AddClient(i + 1, currentDate);
    }
    currentDate = currentDate.AddDays(1);
}

void AddClient(int clientIndex, DateTime dateTime)
{
    var client = new Client {
        Name = List[clientIndex].Name,
        Date = dateTime
    };
    List2.Add(client);
}

这 30 天不需要循环。只需循环直到客户端用完 (i &lt; List.Count) 或者您已经安排了 60 个客户端,即,直到您达到 30 天。如果客户端数量是奇数,i + 1 &lt; List.Count 确保您不超过列表。


如果您想更加灵活地处理每天的客户数量,请使用 2 个循环。一种以ClientsPerDay 的步骤循环遍历源列表,另一种循环ClientsPerDay

const int ClientsPerDay = 2;
DateTime currentDate = DateTime.Now.Date;

for (int i = 0; i < List.Count && i < ClientsPerDay * 30; i += ClientsPerDay) {
    for (int j = 0; j < ClientsPerDay; j++) {
        int clientIndex = i + j;
        if (clientIndex < List.Count) {
            var client = new Client {
                Name = List[clientIndex].Name,
                Date = currentDate
            };
            List2.Add(client);
        }
    }
    currentDate = currentDate.AddDays(1);
}

作为替代方案,您可以提前计算循环次数

int clientCount = Math.Min(List.Count, ClientsPerDay * 30);
for (int i = 0; i < clientCount; i += ClientsPerDay) {
   ...
}

重新开始
在此期间,您已经更改了问题。如果您想在未达到天数但客户端用完的情况下重新开始,您可以使用modulo operator (%) 使索引重新开始。

const int ClientsPerDay = 2, NumDays = 30;
DateTime date = DateTime.Now.Date;
for (int i = 0; i < ClientsPerDay * NumDays; i += ClientsPerDay) {
    for (int j = 0; j < ClientsPerDay; j++) {
        int clientIndex = (i + j) % List.Count; // clientIndex = [0 .. List.Count - 1]
        var client = new Client {
            Name = List[clientIndex].Name,
            Date = date
        };
        List2.Add(client);
    }
    date = date.AddDays(1);
}

另请参阅:Circular array GeeksforGeeks

【讨论】:

  • 我什至不知道你可以用 for 循环做这样的事情。谢谢 Olivier,你的回答比我的问题更清楚。
  • 你实际上打开了我的史前思维,让我能够敏锐地编写代码。谢谢
  • 小修正:循环条件中必须是&amp;&amp;而不是||。我们希望在达到一个条件或达到另一个条件时停止,这意味着只有在满足两个条件(AND)时循环才能继续。
  • 知道我可以在 for 循环中使用两个条件现在给了我更多的游乐场。谢谢
  • 唯一的事情是当达到客户端总数时,您的代码循环结束。我需要循环,直到通过继续使用相同的客户达到 30 天。我将从您的代码中学习并进行修改,使其对我有用。
【解决方案2】:

好吧,我想我理解了这个问题 - 所以我建议你这样做:
首先,只循环一次客户端的名称。 在该循环内,嵌套第二个循环,从 0 计数到 59。 在该循环中,将客户端添加到目标列表,将内部循环计数器 % 30 天添加到当前日期时间值:

// meaningful names - i is kinda "defacto standard" as a for loop counter
for (int i = 0; i < List.Count; i++)
{
    // using j for nesting loops is also kinda "defacto standard"
    for(int j = 0; j < 60; j++)
    {
        // you already know it's a client, use var!
        var client = new Client();
        client.Name = List[record].Name;
        client.Date = currentDate.AddDays(j % 30);
        List2.Add(client);
    }
}

当然,对于这种事情还有更高级的解决方案,比如使用 linq - 但我不确定我是否愿意向 c# 初学者推荐 linq - 我认为最好从基础开始并按照自己的方式工作到高级的东西。

【讨论】:

  • 我没有看到任何提到一个月,这个问题清楚地说明了 30 天,尽管我同意这不是最容易理解的问题。
【解决方案3】:

正如 Olivier Jacot-Descombes 建议的那样:

const int ClientsPerDay = 2;
DateTime currentDate = DateTime.Now.Date;

for (int i = 0; i < List.Count && i < ClientsPerDay * 30; i += ClientsPerDay) {
for (int j = 0; j < ClientsPerDay; j++) {
    int clientIndex = i + j;
    if (clientIndex < List.Count) {
        var client = new Client {
            Name = List[clientIndex].Name,
            Date = currentDate
        };
        List2.Add(client);
    }
}
currentDate = currentDate.AddDays(1);

}

但这一直持续到达到 List.Count。因此,它仅在客户端全部使用之前填充列表。 相反,我正在寻找一种解决方案,该解决方案将循环相同的客户端,直到达到 30 天的限制。 像这样的:

do
{
const int ClientsPerDay = 2;
DateTime currentDate = DateTime.Now.Date;

for (int i = 0; i < List.Count && i < ClientsPerDay * 30; i += ClientsPerDay) {
for (int j = 0; j < ClientsPerDay; j++) {
    int clientIndex = i + j;
    if (clientIndex < List.Count) {
        var client = new Client {
            Name = List[clientIndex].Name,
            Date = currentDate
        };
        List2.Add(client);
    }
}
currentDate = currentDate.AddDays(1);
}
} while (currentDate < currentdate.AddDays(30));

但我的 Do 只是重复工作而不是继续约会。

【讨论】:

    【解决方案4】:

    我猜是这样的吧? UTC 中的所有日期 - 使用规范的日期时间比使用那些看起来很糟糕的偏移更容易。当您需要在终端中显示它们时,您始终可以将它们转换为语言环境,因此直到最后一点都没有理由使用它们。

        public static void Main(string[] args)
        {
            var currentDate   = DateTime.UtcNow;
            var daysInMonth   = DateTime.DaysInMonth;
            var repeats       = 2;
    
            for(var i = 0; i < daysInMonth;i++)
            {
                foreach(var item in List)
                {
                    for(var r = 0; r < repeats;r++)
                    {
                        var client = new Client
                        {
                            Name = item.Name,
                            Date = currentDate.AddDays(i)
                        };
                        List2.Add(client);
                    }
                }
            }
        }
    

    PS:问题真的很糟糕,我什么都不懂。

    【讨论】:

    • 谢谢 eocron,我正在研究你的代码,因为我的计算速度仍然有点慢..
    • 如果您能建议更改问题标题,我将感谢您的帮助
    • 您的解决方案看起来很简单。但是这段代码不是在相同的日期中添加了两次相同的 item.Name 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多