从列表<a> into List<b> C#

时间:2018-10-30 15:06:49

标签: c# linq random

I'm working on a code that assigns a random numbers from List A into a group of objects in List B.

Here is the requirements:

I have a List of Campaigns and List of CampaignRecipients, and I need to cover three scenarios:

  1. When I have equal count on both lists, 2 campaigns and 2 recipients "I have no issue with it at all, it randomly picks a campaignID and assigns it to a randomly picked recipient from List B and so on.
  2. When I have 3 campaigns and 1000 recipients, so it will divide the List of recipients into three groups and assigns each group a randomly picked campaign ID.
  3. When having 5 campaigns and 3 recipients, then it will randomly pick 3 campaigns and assigns them to the recipients.

The problem I'm having is with point 2. It takes a very long time, to the point that the operations start timing out. It distributes the numbers as I want, but it is very slow when dealing with 1k recipients or more.

private static void RandomizeScenarios(ref IList<CampaignLib> cmp, ref IList<CampaignRecipientLib> rec)
{
    IEnumerable<int> RecipientsIds = rec.Select(x => x.ID).ToList();
    IList<int> CampaignsIds = cmp.Select(x => x.CampaignId.Value).ToList();
    int initVal = RecipientsIds.Count() / CampaignsIds.Count;
    int i = 0;

    if (CampaignsIds.Count < rec.Count())
    {
        List<CampaignRecipientLib> tmpRecipients = new List<CampaignRecipientLib>();

        foreach (var item in CampaignsIds)
        {
            i++;
            IEnumerable<int> tmp = null;

            if (i < CampaignsIds.Count) tmp = RecipientsIds.Shuffle().Take(initVal);
            else tmp = RecipientsIds.Shuffle().Take(RecipientsIds.Count());


            RecipientsIds = from r in RecipientsIds where !tmp.Contains(r) select r;

            var PartialRecipients = from r in rec where tmp.Contains(r.ID) select r;


            // HERE IT TAKES A VERY LONG TIME < 35mins for 2.5K objects
            PartialRecipients.ToList().ForEach(r => r.CampaignId = item);

            tmpRecipients.AddRange(PartialRecipients);

        }
        rec = tmpRecipients;
    }
    else if (CampaignsIds.Count == rec.Count())
    {
        foreach (var item in CampaignsIds)
        {
            int tmp = RecipientsIds.Shuffle().Take(1).FirstOrDefault();

            RecipientsIds = from r in RecipientsIds where tmp != r select r;

            rec.FirstOrDefault(x => x.ID == tmp).CampaignId = item;                  
        }
    }
    else if (CampaignsIds.Count > rec.Count())
    {
        foreach (var item in CampaignsIds.PickRandom(RecipientsIds.Count()).OrderBy(x => x))
        {
            int tmp = RecipientsIds.Shuffle().PickRandom(1).FirstOrDefault();

            RecipientsIds = from r in RecipientsIds where tmp != r select r;

            rec.FirstOrDefault(x => x.ID.Equals(tmp)).CampaignId = item;
        }
    }

}

1 个答案:

答案 0 :(得分:3)

您使它变得太复杂了。您可以这样做:

  • 随机播放收件人列表。
  • 第一个(收件人/活动计数的收件人)收件人获得第一个广告系列
  • 下一批收件人获得第二个广告系列
  • Etcetera

通过这种方式,您只需将列表重新排列一次。而且您不必跟踪哪些用户已经拥有广告系列。


示例:

  • 用户:1 2 3 4 5 6
  • 广告系列:1 2

随机播放用户:

  • 用户:(5 3 2 4 1 6)
  • 用户(5 3 2)获得广告系列1
  • 用户(4 1 6)获得广告系列2