3

应用程序的一些背景。这是针对我拥有的 WASP 和 SMPP 发射器帐户的。

我有一个列表<>,其中包含一个对象,该对象具有 SMPP PDU 和发送消息所需的所有对象。此列表包含一个名为“路由标签”的属性,该路由标签将指示将 PDU 提交给哪个服务提供商(Vodacom、MTN、Cell C)。

我有另一个帐户列表,我可以在其中绑定到 SMPP 服务器并发送消息。此列表还包含路由标签并具有发送者帐户的名称。例如,Vodacom 的路由标签是“D082”,我有两个可以同时绑定的帐户。

我现在需要获取第一个 List<> 并更新字段。假设第一个 List<> 有 1000 个项目。我需要将这些(或多或少均匀地)分配给我为第二个 List<> 中提到的每个“路由标签”拥有的所有帐户。

我更愿意使用 linq 或 lambda 来实现所需的功能。

编辑:添加代码示例,以便您好心的人可以帮助我 :-) 对不起标准差,但我很快为你们删除了一些代码。我希望这有助于解决我的问题。

static void Main(string[] args)
    {


        List<MobileAccounts> TransmitterAccounts = new List<MobileAccounts>();//This list contains my transmitter accounts


        MobileAccounts item = new MobileAccounts();
        item.FriendlyName = "Vodacom 1";
        item.RoutingLabel = "D082";
        TransmitterAccounts.Add(item);

        MobileAccounts item1 = new MobileAccounts();
        item1.FriendlyName = "Vodacom 2";
        item1.RoutingLabel = "D082";
        TransmitterAccounts.Add(item1);


        MobileAccounts item2 = new MobileAccounts();
        item2.FriendlyName = "MTN 1";
        item2.RoutingLabel = "D083";
        TransmitterAccounts.Add(item2);


        MobileAccounts item3 = new MobileAccounts();
        item3.FriendlyName = "MTN 2";
        item3.RoutingLabel = "D083";
        TransmitterAccounts.Add(item3);

        MobileAccounts item4 = new MobileAccounts();
        item4.FriendlyName = "MTN 3";
        item4.RoutingLabel = "D083";
        TransmitterAccounts.Add(item4);

        MobileAccounts item5 = new MobileAccounts();
        item5.FriendlyName = "CellC 1";
        item5.RoutingLabel = "D084";
        TransmitterAccounts.Add(item5);

        MobileAccounts item6 = new MobileAccounts();
        item6.FriendlyName = "CellC 2";
        item6.RoutingLabel = "D084";
        TransmitterAccounts.Add(item6);


        List<SubmitSm> col = new List<SubmitSm>();//this list contains messages in a queue ready for sending

        SubmitSm sitem = new SubmitSm();
        sitem.DestAddr = "0722222222";//Vodacom number
        sitem.RoutingLabel = "D082";
        col.Add(sitem);

        SubmitSm sitem1 = new SubmitSm();
        sitem1.DestAddr = "0722222220";//Vodacom number
        sitem1.RoutingLabel = "D082";
        col.Add(sitem1);

        SubmitSm sitem2 = new SubmitSm();
        sitem2.DestAddr = "0722221212";//Vodacom number
        sitem2.RoutingLabel = "D082";
        col.Add(sitem2);

        SubmitSm sitem3 = new SubmitSm();
        sitem3.DestAddr = "0830000000";//MTN number
        sitem3.RoutingLabel = "D083";
        col.Add(sitem3);


        SubmitSm sitem4 = new SubmitSm();
        sitem4.DestAddr = "0833746005";//MTN number
        sitem4.RoutingLabel = "D083";
        col.Add(sitem4);

        SubmitSm sitem5 = new SubmitSm();
        sitem5.DestAddr = "0749999998";//CellC number
        sitem5.RoutingLabel = "D084";
        col.Add(sitem5);

        /*
         * Now this is where I will need
         * to split all the messages in "col"
         * amongst all the transmitter accounts
         * I have. 
         */


    }

public class MobileAccounts
{
    /*Please note not all items 
    are in this class. I have
    * removed some as they are not
    * neccessary for this demo code.               
    */

    //[DataMember]
    public string FriendlyName;

    //[DataMember]
    public string BindName;

    //[DataMember]
    public string BindPassword;

    //[DataMember]
    public string BindHost;

    //[DataMember]
    public string BindPort;

    //[DataMember]
    public string BindType;

    //[DataMember]
    public string ProviderCode;

    //[DataMember]
    public string RoutingLabel;


}

public class SubmitSm
{
   /*Please note not all items 
    are in this class. I have
    * removed some as they are not
    * neccessary for this demo code.               
    */
    public byte DefaultMessageId { get; set; }

    public string DestAddr { get; set; }

    public byte DestAddrNpi { get; set; }

    public byte DestAddrTon { get; set; }

    public string MessageText { get; set; }        

    public byte PriorityFlag { get; set; }

    public byte ProtocolId { get; set; }

    public byte RegisteredDelivery { get; set; }                

    public string ScheduleDeliveryTime { get; set; }

    public string ServiceType { get; set; }

    public string SourceAddr { get; set; }

    public byte SourceAddrNpi { get; set; }

    public byte SourceAddrTon { get; set; }

    public string ValidityPeriod { get; set; }

    public string RoutingLabel { get; set; }

}

感谢所有做出贡献的人。@NinjaNye 您的解决方案很接近,但不完全符合我的要求。不过我很感激你的努力。

我快到了,但我很挣扎。有人可以帮我找出如下所示的子选择:

List<IGrouping<string, MobileAccounts>> sad1 = TransmitterAccounts.GroupBy(y => y.RoutingLabel).ToList();
col = (List<SubmitSm>)col.Select
                                (x =>
                                    {
                                         x.ServiceType = sad1.Where
                                                               (z =>
                                                                   z.Key==     x.ServiceType
                                                                        )                                                    
                                                                        .Select
                                                                            (y =>
                                                                                    new
                                                                                    {
                                                                                        //this should return the Transmitter account that has the lowest count

                                                                                        TransmitterAccount = y.OrderBy(ui => x.ServiceType.Count()).Select(ui => ui.FriendlyName).First()
                                                                                    }
                                                                            ).First().TransmitterAccount;                                                  

                                              return x;
                                      }
                                    ).ToList();
4

2 回答 2

2

我在这里看到的 Linq 的唯一用途是使用,.Skip()但是.Take()我创建了一个扩展方法来整理一下。这意味着您可以简单地编写以下内容来拆分任何IEnumerable.

// In your example above you need to replace `items` with your `col` variable
var result = items.Split(transmitter.Count());

扩展方法

http://www.ninjanye.co.uk/2013/07/splitting-distributing-list-objects.html

http://jnye.co/Posts/10/evenly-splitting-distributing-a-list-of-objects-using-linq-and-extension-methods

public static class EnumerableExtensions
{
    public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> source, int groups)
    {
        var listedSource = source.ToList();
        int extra;
        int groupSize = Math.DivRem(listedSource.Count(), groups, out extra);

        while (listedSource.Any())
        {
            int newSize = groupSize;
            if (extra > 0)
            {
                newSize++;
                extra--;
            }
            yield return listedSource.Take(newSize);
            listedSource = listedSource.Skip(newSize).ToList();
        }
    }
}

结果

我把它设置为一个快速命令程序来测试

以下是一些结果,您可以查看项目是如何拆分的: 拆分的示例输出

初始帖子(现在在上面重构)

像这样的东西应该这样做......但是我已经简化了这个例子

        // This is your transmitter count
        int groups = 4; 
        // These are your SMS's
        List<int> values = new List<int>(){1,2,3,4,5,6,7,8,9};

        //Calculate group size
        int extra;
        int groupSize = Math.DivRem(values.Count, groups, out extra);

        var result = new List<IEnumerable<int>>();
        while (values.Any())
        {
            int newSize = groupSize;
            if (extra > 0)
            {
                // Account for extras
                newSize++;
                extra--;
            }
            result.Add(values.Take(newSize));
            values = values.Skip(newSize).ToList();
        }

        return result;

于 2013-07-16T17:23:30.987 回答
-1

你应该避免 LINQ 有副作用。但是您可以像这样将对象附加到列表中。

        List<MobileAccounts> mas = new List<MobileAccounts>();
        List<SubmitSm> sms = new List<SubmitSm>();

        var result = mas.Select(ma => new {Sm=(sms.First(sm => sm.RoutingLabel == ma.RoutingLabel)),Ma=ma});
        foreach (var r in result)
        {
            //update Properties here
        }
于 2013-07-16T17:00:32.140 回答