我想获取一个包含约12个对象的字符串列表,并将其拆分为两个字符串列表,但将其完全随机化。
列表示例:
清单1:
EXAMPLE 1
EXAMPLE 2
EXAMPLE 3
EXAMPLE 4
EXAMPLE 5
EXAMPLE 6
EXAMPLE 7
EXAMPLE 8
在这里应用一些逻辑...
结果给了我两个清单: 清单1:
EXAMPLE 5
EXAMPLE 6
EXAMPLE 1
EXAMPLE 8
清单2:
EXAMPLE 2
EXAMPLE 3
EXAMPLE 4
EXAMPLE 7
我是C#MVC的新手,所以我在Stack上找到了一些答案,但没有一个能够回答我的问题。
编辑: 到目前为止,我已经尝试过给我一个随机的团队成员。我现在想对此进行扩展,并如上所述创建两个列表。
[HttpPost]
public ActionResult Result(Models.TeamGenerator model)
{
var FormNames = model.Names;
string[] lines = FormNames.Split(
new[] { Environment.NewLine },
StringSplitOptions.None);
List<string> listOfLines = new List<string>();
foreach (var i in lines)
{
listOfLines.Add(i);
}
string[] result1 = listOfLines.Where(item => item != string.Empty).ToArray();
Random genRandoms = new Random();
int aRandomTeam = genRandoms.Next(listOfLines.Count);
string currName = listOfLines[aRandomTeam];
return View();
}
*编辑**感谢您的解决方案!现在,我的应用程序开始运行,并设法将其发布到网络https://www.teamgenerator.online。
答案 0 :(得分:3)
true
填充一堆布尔值,用false
填充另一半。true
,则将该元素包括在第一个列表中;否则,将其添加到列表中。否则将其包括在第二个列表中。如果重要的话,这种方法可以使项目保持与原始数组相同的顺序。 (如果没有,则只需将整个字符串数组混洗,然后取前一半和后一半)。
示例代码:
using System;
using System.Linq;
namespace ConsoleApp1
{
class Program
{
public static void Main()
{
var strings = Enumerable.Range(1, 20).Select(i => i.ToString()).ToList();
var rng = new Random();
int n = strings.Count;
var include = // Create array of bools where half the elements are true and half are false
Enumerable.Repeat(true, n/2) // First half is true
.Concat(Enumerable.Repeat(false, n-n/2)) // Second half is false
.OrderBy(_ => rng.Next()) // Shuffle
.ToArray();
var list1 = strings.Where((s, i) => include[i]).ToList(); // Take elements where `include[index]` is true
var list2 = strings.Where((s, i) => !include[i]).ToList(); // Take elements where `include[index]` is false
Console.WriteLine(string.Join(", ", list1));
Console.WriteLine(string.Join(", ", list2));
}
}
}
这是一种完全不同的方法,它使用标准算法的修改版本从N个项目中选择K个项目(在这种情况下,K = N / 2):
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
class Program
{
public static void Main()
{
var strings = Enumerable.Range(1, 20).Select(n => n.ToString()).ToList();
var list1 = new List<string>();
var list2 = new List<string>();
var rng = new Random();
int available = strings.Count;
int remaining = available / 2;
foreach (var s in strings)
{
if (rng.NextDouble() < remaining / (double) available)
{
list1.Add(s);
--remaining;
}
else
{
list2.Add(s);
}
--available;
}
Console.WriteLine(string.Join(", ", list1));
Console.WriteLine(string.Join(", ", list2));
}
}
}
这种方法比我的第一个解决方案性能更好,但是由于您的清单只有大约12个项目,因此这对您的问题而言并不重要。
答案 1 :(得分:2)
首先,尝试使用Random
函数对列表进行混洗
static class MyExtensions
{
private static Random rng = new Random();
public static void Shuffle<T>(this IList<T> list)
{
int n = list.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
}
然后使用Linq
static void Main(String[] args)
{
List<string> examples = new List<string>();
for(int i=1;i<=12;i++)
{
examples.Add($"Example {i}");
}
examples.Shuffle();
var firstlist = examples.Take(examples.ToArray().Length / 2).ToArray();
Console.WriteLine(String.Join(", ", firstlist));
var secondlist = examples.Skip(examples.ToArray().Length / 2).ToArray();
Console.WriteLine(String.Join(", ", secondlist));
Console.ReadLine();
}
输出看起来像这样
Example 6, Example 8, Example 3, Example 9, Example 5, Example 2
Example 10, Example 11, Example 4, Example 7, Example 12, Example 1
答案 2 :(得分:2)
您目前仅生成一个随机数并获得一个值。您需要做的是将其放入循环中,该循环的运行次数是列表中项目的一半。
var genRandoms = new Random();
var numberRequired = listOfLines.Count/2;
var output = new List<string>();
for (var i=0; i<numberRequired; i++)
{
var aRandomTeam = genRandoms.Next(listOfLines.Count);
output.Add(listOfLines[aRandomTeam]);
listOfLines.RemoveAt(aRandomTeam);
}
此外,这是开头:
string[] lines = FormNames.Split(
new[] { Environment.NewLine },
StringSplitOptions.None);
List<string> listOfLines = new List<string>();
foreach (var i in lines)
{
listOfLines.Add(i);
}
string[] result1 = listOfLines.Where(item => item != string.Empty).ToArray();
可以重写为:
var listOfLines = FormNames.Split(
new[] { Environment.NewLine },
StringSplitOptions.RemoveEmptyEntries).ToList();
作为拆分的一部分删除空项目,并使用内置方法将其转换为列表。
答案 3 :(得分:1)
所以我在控制台应用程序中写了一个示例,但是这个概念的工作原理是一样的...请参见下面的代码块中的注释
样品清单
var fullList = new List<string>()
{
"ITEM 01", "ITEM 02", "ITEM 03", "ITEM 04", "ITEM 05", "ITEM 06",
"ITEM 07", "ITEM 08", "ITEM 09", "ITEM 10", "ITEM 11", "ITEM 12"
};
初始化两个列表以拆分值
var list1 = new List<string>();
var list2 = new List<string>();
创建两个随机列表
// Initialize one Random object to use throughout the loop
var random = new Random();
// Note: Start at count and count down because we will alter the count of the list
// so counting up is going to mess up. Ex: Count = 4, Remove 1 (Count = 3), Loop won't go to 4
for(int i = fullList.Count; i > 0; i--)
{
// Pull random index
var randomIndex = random.Next(fullList.Count);
// Pull item at random index
var listItem = fullList[randomIndex];
// If i is even, put it in list 1, else put it in list 2.
// You could do whatever you need to choose a list to put it
if (i % 2 == 0)
list1.Add(listItem);
else
list2.Add(listItem);
// Remove random item from the full list so it doesn't get chosen again
fullList.RemoveAt(randomIndex);
}
结果
Console.WriteLine("LIST 1");
Console.WriteLine(string.Join(Environment.NewLine, list1));
Console.WriteLine();
Console.WriteLine("LIST 2");
Console.WriteLine(string.Join(Environment.NewLine, list2));
-----------------------
LIST 1
ITEM 05
ITEM 04
ITEM 12
ITEM 11
ITEM 08
ITEM 01
LIST 2
ITEM 02
ITEM 03
ITEM 09
ITEM 06
ITEM 10
ITEM 07
答案 4 :(得分:0)
这是一个简单的solution,与您尝试解决此问题的方式一致。
主要逻辑如下:
while there are still items in the master list:
choose a random number [0,list.count) as the current target index
choose a random number [0,1] as the current target list to add to
add the item chosen randomly to the randomly selected list
remove the item chosen from the master list
代码如下:
var random = new Random();
var list = new List<string> { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
var newList1 = new List<string>();
var newList2 = new List<string>();
while(list.Count > 0)
{
//choose the index randomly
int index = random.Next(list.Count);
//get the item at the randomly chosen index
string curItem = list[index];
//choose the list randomly(1==newList1, 2==newList2)
int listChoice = random.Next(2);
//Add the item to the correct list
if(listChoice == 1)
{
newList1.Add(curItem);
}
else
{
newList2.Add(curItem);
}
//finally, remove the element from the string
list.RemoveAt(index);
}