LINQ/Lambda更新通过将项目拆分成偶数组来列出项目
应用程序的一些背景。这是针对我拥有的WASP和SMPP发射器帐户。LINQ/Lambda更新通过将项目拆分成偶数组来列出项目
我有一个列表<>它包含一个对象,该对象具有SMPP PDU的所有必需对象并发送消息。 此列表包含名为“路由标签”的属性,路由标签将指示哪个服务提供商将PDU提交给(Vodacom,MTN,Cell C)。
我有另一个帐户列表,我可以绑定到SMPP服务器并发送消息。该列表还包含路由标签并且具有发射器帐户的名称。因此,例如Vodacom的路由标签是“D082”,我有两个帐户可以同时绑定。
我现在需要采取第一个清单<>并更新字段。可以说第一个列表<>有1000个项目。我需要将这些(或多或少均匀地)分配给我提到的第二个列表<>中出现的每个“路由标签”的所有帐户。
我宁愿使用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();
唯一使用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
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;
你应该避免带有副作用的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
}
欢迎来到Stack Overflow!虽然我确信可以用一些背景来理解你的问题,但是很难看到相关的代码。看起来您在这里有两种自定义类型 - 要传输的项目以及路由信息。显示这些类的相关属性将有所帮助。这也有助于查看您编写的代码来尝试自己解决此问题 - 修复别人的代码通常比从头开始编写新代码更容易。 – dasblinkenlight
问题很简单,我有一堆去不同商店的水果。我有一堆商店,每个商店都有几个篮子。我想将每个商店指定的水果均匀分配到篮子之间。然而,答案并不是那么容易......在这个问题上工作,但也许有人比我更聪明会先到达那里:p –
@DaveWilliams:哈哈哈!!!今天早上你的评论使我的脸上露出了微笑。但是,戴夫,你是100%正确的。我希望上面的代码会有帮助。 – BossRoss