LINQ/Lambda更新通过将项目分为偶数组来列出它们 [英] LINQ/Lambda update List items by spliting them into even groups
问题描述
应用程序的某些背景.这是我拥有的WASP和SMPP传输者帐户.
Some background of the application. This is for a WASP and SMPP transmitter accounts I have.
我有一个列表<>,其中包含一个对象,该对象具有SMPP PDU和发送消息的所有必需对象. 该列表包含一个称为路由标签"的属性,路由标签将指示向哪个服务提供商提交PDU(Vodacom,MTN,Cell C).
I have a list<> that contains an object that has all the necessary objects for a SMPP PDU and to send a message. This list contains a property called "Routing Label" the routing label will indicate which one of the service providers to submit the PDU to (Vodacom, MTN, Cell C).
我还有另一个帐户列表,可以绑定到SMPP服务器并通过其发送消息.此列表还包含路由标签,并具有发送方帐户的名称.例如,Vodacom的路由标签为"D082",我有两个可以同时绑定的帐户.
I have another list of accounts where I can bind to the SMPP server and send messages over. This list also contains the routing label and has a name for the transmitter account. So for example Vodacom's routing label is "D082" and I have two accounts that I can bind to simultaneously.
我现在需要获取第一个列表<>并更新字段.假设第一个List<>具有1000个项目.我将需要将这些(或多或少平均)分配给我提到的第二个List中出现的每个路由标签"的所有帐户.
I now need to take the first List<> and update the fields. Lets say the first List<> has 1000 items. I will need to split these(more or less evenly) amongst all the accounts I have for each "Routing Label" that occurs in the second List<> mentioned.
我希望使用linq或lambda实现所需的功能.
I would prefer to achieve the desired functionality using linq or lambda.
已编辑:添加了代码示例,以便善良的人们可以帮助我:-)对不起糟糕的标准,但我迅速为您剥离了一些代码.我希望这可以解决我的问题.
Edited:Added code example so that you kind people may help me :-) Sorry for the poor standard but I quickly stripped some code out for you guys. I hope this helps with my problem.
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您的解决方案很接近,但不完全符合我的要求.不过,我非常感谢您的努力.
Thank you to all who have contributed. @NinjaNye your solution is close but does not exactly fit my requirements. I do appreciate your effort though.
我思考我快到了,但我在挣扎.有人可以帮助我找出下面显示的子选项吗?
I think I am almost there but I am struggling. Can someone, anyone please help me figure out the sub select shown below:
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();
推荐答案
我在这里看到的Linq唯一用途是使用.Skip()
和.Take()
,但是我创建了一个扩展方法来整理内容.少量.这意味着您只需编写以下内容即可拆分任何IEnumerable
.
The only use of Linq I can see here would be the use of .Skip()
and .Take()
however I have created an extension method to tidy things up a bit. This will mean you can simply write the following to split any 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
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();
}
}
}
结果
我将其设置为要测试的快速命令程序
I set this up as a quick command program to test
以下是一些结果,因此您可以查看项目的拆分方式:
Here are some results so you can see how items are split:
初始帖子(现已在上方重构)
类似的事情应该可以...但是我简化了示例
Something like this should do it... however I have simplified the example
// 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;
这篇关于LINQ/Lambda更新通过将项目分为偶数组来列出它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!