2013-01-10 58 views
0

我可以半@ ss这个,但我想要一个干净的方式来做到这一点,不会稍后创建任何麻烦。将字符串数组分割为多个部分

private String[][] SplitInto10(string[] currTermPairs) 
{ 
    //what do i put in here to return 10 string arrays 
    //they are all elements of currTermPairs, just split into 10 arrays. 
} 

所以我基本上要分割一个字符串数组(currTermPairs)等分为10个或11个不同串阵列。我需要确保没有数据丢失,并且所有元素都成功传输了

编辑: 给出了一个n大小的字符串数组。需要发生的是该方法需要从给定的字符串数组中返回10个字符串数组/列表。换句话说,将数组分成10个部分。

例如,如果我有

A B C D E F G H I J K L M N O P Q R S T U 

我需要它分裂成10个阵列或11个字符串数组取决于尺寸,所以在这种情况下,我将不得不

A B 
C D 
E F 
G H 
I J 
K L 
M N 
O P 
Q R 
S T 
U <--Notice this is the 11th array and it is the remainder 
+2

已知: _____预计:______ –

+0

我不明白吗? 如果你问我给出了什么和期望什么, 你可以在方法中看到一个字符串数组,并且期望它被等分为10个不同部分 – Ramie

+0

@Ramie:我们不知道什么您的要求。某些给定输入的预期输出是什么? – Patrick

回答

2

这不是使用LINQ的解决方案,如果你要习惯阵列和for循环:

// Determine the number of partitions. 
int parts = currTermPairs.Length < 10 ? currTermPairs.Length : 10; 

// Create the result array and determine the average length of the partitions. 
var result = new string[parts][]; 
double avgLength = (double)currTermPairs.Length/parts; 

double processedLength = 0.0; 
int currentStart = 0; 
for (int i = 0; i < parts; i++) { 
    processedLength += avgLength; 
    int currentEnd = (int)Math.Round(processedLength); 
    int partLength = currentEnd - currentStart; 
    result[i] = new string[partLength]; 
    Array.Copy(currTermPairs, currentStart, result[i], 0, partLength); 
    currentStart = currentEnd; 
} 
return result; 

项目总数可能不被10整除的问题是如何将分配不同长度的零件。在这里,我尝试平均分配它们。注意铸造(double)currTermPairs.Length。这是获得浮点除法而不是整数除法所必需的。

这里是一个小的测试方法:

const int N = 35; 
var arr = new string[N]; 
for (int i = 0; i < N; i++) { 
    arr[i] = i.ToString("00"); 
} 

var result = new PatrtitioningArray().SplitInto10(arr); 
for (int i = 0; i < result.Length; i++) { 
    Console.Write("{0}: ", i); 
    for (int k = 0; k < result[i].Length; k++) { 
     Console.Write("{0}, ", result[i][k]); 
    } 
    Console.WriteLine(); 
} 

它的输出是(用35个元素):

0: 00, 01, 02, 03, 
1: 04, 05, 06, 
2: 07, 08, 09, 
3: 10, 11, 12, 13, 
4: 14, 15, 16, 17, 
5: 18, 19, 20, 
6: 21, 22, 23, 
7: 24, 25, 26, 27, 
8: 28, 29, 30, 31, 
9: 32, 33, 34, 
0

我'd说创建一个List<List<string>>包含10或11(你实际想要的数字)List<string> s,并做这样的事情:

int i = 0; 
int index; 
foreach(string s in src) 
{ 
    index = i % lists.Length; //lists is the List<List<string>> 
    lists[index].Add(s); 
    i++; 
} 

当然,如果原始列表中至少有10个或11个项目,则只能分成10或11个列表。

5

使用剩余% operator代替,这里的LINQ的方法:

string[][] allArrays = currTermPairs 
      .Select((str, index) => new { str, index }) 
      .GroupBy(x => x.index % 10) 
      .Select(g => g.Select(x => x.str).ToArray()) 
      .ToArray(); 

Demo(每个阵列2串)

+0

现在正在测试。例如,如果我在currTermPairs数组中有7个元素,它会做什么?它会把它放到前一个,并让它有3个元素,还是会为它创建一个全新的数组? – Ramie

+1

第一个会得到4和第二个3(在我的例子中有两个数组)。 –

+0

完美地工作,谢谢。 – Ramie

0

下交示出了用于分割阵列一个很好的例子:

C# Splitting An Array

它包含自定义拆分和中点拆分。

+0

更多的评论/请求重复的链接,而不是答案。 – birryree

0

这可以按顺序排列(即{1,2},{3,4},{5,6},{7,8},{9,10},{11, 12},{13,14},{15,16},{17,18},{19,20},{21}):

int groupSize = items.Length/10; 
    string[][] sets = items.Select((str, idx) => new { index = idx, value = str }) 
          .GroupBy(a => a.index/groupSize) 
          .Select(gr => gr.Select(n => n.value).ToArray()) 
          .ToArray(); 

如果你有102项,这将给你10 10个项目的数组,以及2个项目的数组(其余部分)。这是你所期望的吗?

0

使用MoreLinqBatch扩展方法:

private String[][] SplitIntoParts(string[] items, int equalPartsCount) 
{ 
    var batches = items.Batch(items.Count()/equalPartsCount); 
    return batches.Select(x => x.ToArray()).ToArray(); 
}