C# 将一个数组分成多个较小的数组(随机)
Posted
技术标签:
【中文标题】C# 将一个数组分成多个较小的数组(随机)【英文标题】:C# Separating An Array Into Multiple Smaller Arrays (Randomly) 【发布时间】:2018-01-22 08:34:04 【问题描述】:我正在为我的朋友和我用 c# 制作一个 DISCORD.NET BOT,这是我第一次使用这种语言(我使用 VB.NET,但这里的语法对我来说是全新的)。
我的“问题”是我的命令之一“!squads”接受任意数量的用户名,并将用户分成团队,这样我们就不必自己做,也不必为最后被选中的人感到难过。我不会解释我的代码,它包含在下面并且非常简单。
我的问题是当输入 6 个或 7 个名字时,5 个很容易做到。但是对于 6,我想要 4 和 2 两队,7 两队 4 和 3 随机挑选。
这是我对如何执行此操作的想法,但我认为这会很混乱,所以我想请一些指点!对于 6 个名称,创建 2 个数组,其中最大项为 2 和 4,首先随机填充 2,然后将其余的推到 4。对于 7 执行相同操作,先填充 3 的团队,然后将其余的推到 4。我相信这是一种比从一个数组到另一个数组来回更有效的方法。但是,我可能需要从主数组中删除选定的用户,每次都重新索引数组,这样我就不会再次选择同一个人,并且还需要更改选择指数。我可以做到这一切,但它会很草率,有没有办法在没有 60-70 行 for 和 if 循环的情况下干净地做到这一点?
这是我的代码,谢谢! :)
[Command("Squads")]
public async Task CreateSquads(params string[] usersArray)
int totalUsers = usersArray.Length;
Random squadSelector = new Random();
string squadsMessage;
if (totalUsers < 5)
squadsMessage = "I am sensing 4 or less names, just play squads, clowns.";
else if (totalUsers == 5)
string selectedUser = usersArray[squadSelector.Next(0, usersArray.Length)];
squadsMessage = "Tough luck " + selectedUser + ", better luck next time!";
else if (totalUsers == 6)
// Split users into two teams of 2 and 4
squadsMessage = "6 people."; // Placeholder
else if (totalUsers == 7)
// Split users into two teams of 3 and 4
squadsMessage = "7 people."; // Placeholder
else
// More than 7 people. (not coding for this)
squadsMessage = "We have this many friends? Wut.";
// Originally used this just to spit out the names for testing
//for (int i = 0; i < totalUsers.Length; i++)
//
// await Context.Channel.SendMessageAsync(totalUsers[i]);
//
await Context.Channel.SendMessageAsync(squadsMessage);
更新的代码,完美运行!谢谢大家! :)
[Command("Squads")]
public async Task CreateSquads(params string[] usersArray)
string[] squadOne;
string[] squadTwo;
int totalUsers = usersArray.Length;
Random squadSelector = new Random();
StringBuilder sb = new StringBuilder();
string squadsMessage;
if (totalUsers < 5)
squadsMessage = "I am sensing 4 or less names, just play squads, morons.";
else if (totalUsers >= 5 && totalUsers <= 7)
// 5 users becomes 4 and 1; 6 users becomes 4 and 2; 7 users becomes 4 and 3
usersArray = usersArray.OrderBy(i => squadSelector.Next()).ToArray();
squadOne = usersArray.Take(4).ToArray();
squadTwo = usersArray.Skip(4).Take(totalUsers - 4).ToArray();
sb.Append("__**Squad One:**__");
sb.Append(Environment.NewLine);
for (int i = 0; i < squadOne.Length; i++)
sb.Append(squadOne[i]);
sb.Append(Environment.NewLine);
sb.Append(Environment.NewLine);
if (totalUsers == 5)
sb.Append("__**LOL, Loser:**__");
else
sb.Append("__**Squad Two:**__");
sb.Append(Environment.NewLine);
for (int i = 0; i < squadTwo.Length; i++)
sb.Append(squadTwo[i]);
sb.Append(Environment.NewLine);
squadsMessage = sb.ToString();
else
// More than 7 people.
squadsMessage = "We have this many friends? Wut.";
await Context.Channel.SendMessageAsync(squadsMessage);
【问题讨论】:
好吧,我并不是说这些都很难,但 5 很容易在 2 行中完成,我希望 6 和 7 尽可能紧凑。我只是不明白我如何能有效地做到这一点,并且尽可能地少行。另外,我可能想多了,我从来没有这样做过。 @mjwills:从代码的外观来看,不同之处在于 5 有一个团队和一个“其余”团队,所以它只需要随机选择一个人并宣布那个人是谁曾是。这可以扩展,但 OP 正确地意识到这不一定是最好的方法。 @Chris 准确地说,下面接受的答案非常适合我的需要。我可能会将其应用于数组中 5 个项目的情况,并将一个人纳入他们自己的团队,以进一步提高笑声。非常感谢大家! 【参考方案1】:我会这样做:
var usersArray = new string[] "1", "2", "3", "4", "5", "6", "7" ;
var r = new Random();
usersArray = usersArray.OrderBy(i => r.Next()).ToArray();
var firstGroup = usersArray.Take(3).ToArray();
var secondGroup = usersArray.Skip(3).Take(4).ToArray();
带有 OrderBy(i => r.Next()) 的行将随机排序它们。然后,您可以轻松地将项目分成 2 组。 您也可以将此代码提取到方法中:)
【讨论】:
效果很好,非常感谢。我完全忘记了使用 LINQ。第一支队伍很快就被淘汰了,第二支队伍出现了短暂的延迟,但我认为这可能是由于我的笔记本电脑的能力造成的。 @haag1:最后两行都应该几乎立即运行。如果延迟只是您的机器人输出两行文本,那么这可能只是机器人的节流或网络延迟(因为它在发送下一行之前等待确认一行)。不过,从 7 个项目的数组中跳过和获取的实际运行时间应该基本上为零。 @Chris 我发现了我的问题,这是将团队分开分配到服务器,我决定包含一个字符串生成器并将整个两个团队附加到一个字符串中然后发送。问题已解决(:以上是关于C# 将一个数组分成多个较小的数组(随机)的主要内容,如果未能解决你的问题,请参考以下文章