我想编写一个方法,将一个字符串数组分成一个 n 单独的数组,每个数组大约是我指定的大小。
例如,如果我要分割的数组有23个元素,那么如果我指定7作为元素的近似数量:
1st array with 8 elements
2nd array with 8 elements
3rd array with 7 elements
另一个例子是如果有100个元素,我为每个数组指定18个元素,那么:
1st array 20
2nd array 20
3rd array 20
4th array 20
5th array 20
到目前为止,我知道该函数需要返回一个字符串数组列表,但我不知道该怎么办:
private List<string[]> divStrings(int ExpectedStringsPerArray,
string[] AllStrings)
{
// ...
}
数组的数量为
Math.Floor(AllStrings.Count()/ExpectedStringsPerArray)
如何在C#中将数组划分为单独的数组?
答案 0 :(得分:4)
我可能会错误地解释你的问题,因为这似乎太容易了:
在代码中:
private static List<string[]> DivideStrings(int expectedStringsPerArray, string[] allStrings)
{
List<string[]> arrays = new List<string[]>();
int arrayCount = allStrings.Length / expectedStringsPerArray;
int elemsRemaining = allStrings.Length;
for (int arrsRemaining = arrayCount; arrsRemaining >= 1; arrsRemaining--)
{
int elementCount = elemsRemaining / arrsRemaining;
string[] array = CopyPart(allStrings, elemsRemaining - elementCount, elementCount);
arrays.Insert(0, array);
elemsRemaining -= elementCount;
}
return arrays;
}
private static T[] CopyPart<T>(T[] array, int index, int length)
{
T[] newArray = new T[length];
Array.Copy(array, index, newArray, 0, length);
return newArray;
}
当像这样使用时:
const int count = 23;
const int estimate = 7;
string[] strings = Enumerable.Range(1, count).Select(s => s.ToString()).ToArray();
var list = DivideStrings(estimate, strings);
foreach (var arr in list)
Console.WriteLine(String.Join(" ", arr));
打印:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
答案 1 :(得分:3)
您可以使用Enumerable.Range
获取分割计数,然后使用Linq
Skip
和Take
选择项目以选择数组。
示例:
public List<string[]> divStrings(int count, string[] array)
{
long remainder;
long divCount = Math.DivRem(array.Count(), count, out remainder);
int ajustedCount = (int)((divCount > remainder)
? (divCount / remainder)
: (remainder / divCount)) + count;
int groupCount = (ajustedCount * divCount) > array.Count()
? (int)divCount
: (int)divCount++;
return Enumerable.Range(0, groupCount).Select(g => array.Skip(g * ajustedCount).Take(ajustedCount).ToArray()).ToList();
}
这可能是一个方便的扩展方法
public static class Extensions
{
public static List<T[]> SplitEven<T>(this T[] array, int count)
{
long remainder;
long divCount = Math.DivRem(array.Count(), count, out remainder);
int ajustedCount = (int)((divCount > remainder)
? (divCount / remainder)
: (remainder / divCount)) + count;
int groupCount = (ajustedCount * divCount) > array.Count()
? (int)divCount
: (int)divCount++;
return Enumerable.Range(0, groupCount).Select(g => array.Skip(g * ajustedCount).Take(ajustedCount).ToArray()).ToList();
}
}
用法:
string[] test = new string[]{};
var result = test.Split<string>(7);
int[] test = new int[]{};
var result = test.Split<int>(7);
答案 2 :(得分:2)
你走了。请记住,您可以将列表更改为.ToArray()
的数组,使用.ToList()将数组更改为列表。这就是我将它们全部列为所有列表的原因。
List<List<string>> divStrings(int ExpectedStringsPerArray, List<string> AllStrings)
{
//Set what we're currently up to in the array
var espa = ExpectedStringsPerArray;
var ListOfLists = new List<List<string>>();
//Add the first bunch of elements to the list of lists.
ListOfLists.Add(AllStrings.Take(ExpectedStringsPerArray).ToList());
//While we still have elements left to get out
while (AllStrings.Skip(espa).Take(ExpectedStringsPerArray).Count() != 0)
{
//Add the list data we're currently up to to the list of lists
ListOfLists.Add(AllStrings.Skip(espa).Take(ExpectedStringsPerArray).ToList());
//Offset what we're up to so next time we're getting the next lot of data
espa += ExpectedStringsPerArray;
}
return ListOfLists;
}
请使用以下方式调用:
divStrings(30,testList);
答案 3 :(得分:1)
回答这个问题。我遇到了这个并以我的方式回答。
我不确定你的近似是什么意思,我认为不应该这样做。您必须确定您要查找的数组大小应该是多少。下面是未经测试的代码示例。
List<List<int>> lists = new List<List<int>>();
const int myLimit = 20;
var numbers = (from n in myArray select n).ToList();
while (numbers.Any())
{
var list = (from number in numbers select number).Take(myLimit).ToList();
numbers.RemoveRange(0, list.Count());
lists.Add(list);
}
// Now lists should have list of equal number if items in each. Last one may be an exception.
希望它有所帮助。