.net 遍历List并回顾性地添加到类属性

2nbm6dog  于 2022-12-14  发布在  .NET
关注(0)|答案(2)|浏览(101)

I have a schedule which I want to send notifications on. I want to evenly distribute a list throughout a model in order to ensure we have the best reach.
I want to loop through a list of items which it fetched from the database and add them to a time slot on a class which has been specified.
Once it reaches the end of the specified time frame, it'll loop back to the start and keep doing this until all of the users have been allocated a time slot.
I have created the following model for the time slots:

public class Slots 
{
    public List<string> NineAM { get; set; } = default!;

    public List<string> TenAM { get; set; } = default!;

    public List<string> OnePM { get; set; } = default!;

    public List<string> TwoPM { get; set; } = default!;
}

The reason it stores strings is for the email whom the notification is going to be dispatched to. Basically I can check if they have it any items and then dispatch accordingly.
I am unsure how to approach the for loop in order to evenly distribute them out but the current code I have is:

var users = _context.Users.ToListAsync();

users.ForEach(user => 
{
   // Add first user to 9AM
   // Add seconds user to 10AM
  // Add third user to 1PM
   // Add fourth user to 2PM
   // Add fifth user to 9AM
});

Resolution:
Based on the accepted answer I did the following.

  1. Reverted from using a class and properties and arranged my date / times in an array.
private DateTime[] GetTimeSlots()
{
  return new DateTime[]
  {
    DateTime.Now.Date.Add(new TimeSpan(9, 0, 0)),
    DateTime.Now.Date.Add(new TimeSpan(10, 0, 0)),
    DateTime.Now.Date.Add(new TimeSpan(13, 0, 0)),
    DateTime.Now.Date.Add(new TimeSpan(14, 0, 0))
  }
}
  1. Updated the loop.
var slots = GetTimeSlots();

foreach (var user in users)
{
  var userIndex = users.indexOf(user);
  var targetSlotIndex = userIndex % slots.Length;
  
  var targetTime = slots[targetSlotIndex];
  // This resulted in the time iterating accordingly.
}

This allowed for time slots to be much more dynamic when adding / removing new ones.

7rtdyuoh

7rtdyuoh1#

您有4个插槽,因此将用户分为4组,并将他们添加到相应的插槽中,您可以使用%操作符查看他们进入哪个插槽。

foreach(var user in users)
{
    switch (users.IndexOf(user) % 4)
    {
        case 0:
           //add to NineAM
           break;
        case 1:
           //add to TenAM
           break;
        case 2:
           //add to OnePM
           break;
        case 3:
           //add to TwoPM
           break;
    }
}
igetnqfo

igetnqfo2#

This is a Round Robin distribution, and I just recently had to write something similar. I also used the % operator for my solution.
The Resolution you posted is unnecessarily inefficient though. You don't need to call users.indexOf(user), because there is a cost to search the list for the user and that cost can be eliminated. It is far more efficient to do this by just tracking the iteration of the loop that you are in.
get rid of this

var userIndex = users.indexOf(user);

and use one of these solutions

var slots = GetTimeSlots();
for(int i=0; i < users.Count; i++)
{
    var index = i % slots.Count;
    var targetTime = slots[index];
}

OR 

int i = 0;
var slots = GetTimeSlots();
foreach (var user in users)
{
    var index = i % slots.Count;
    var targetTime = slots[index];
    i++;
}

相关问题