如何将一个数组分成一组n个元素?
问题描述:
什么是组的最佳方式的阵列到每个n个元素的数组的列表在c#4如何将一个数组分成一组n个元素?
E.g
string[] testArray = { "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8" };
应分成如果我们n = 3的采取。
string[] A1 = {"s1", "s2", "s3"};
string[] A2 = {"s4", "s5", "s6"};
string[] A3 = {"s7", "s8"};
可能是一种使用LINQ的简单方法?
答
这将产生具有3种元素的字符串数组的数组:如果它实际上是你用,而不是一般的IEnumerables,特别是如果该阵列是非常大的工作阵列
int i = 0;
var query = from s in testArray
let num = i++
group s by num/3 into g
select g.ToArray();
var results = query.ToArray();
答
我不认为有一个伟大的内置方法,但你可以写一个如下。
public static IEnumerable<IEnumerable<T>> GroupInto<T>(
this IEnumerable<T> source,
int count) {
using (var e = source.GetEnumerator()) {
while (e.MoveNext()) {
yield return GroupIntoHelper(e, count);
}
}
}
private static IEnumerable<T> GroupIntoHelper<T>(
IEnumerator<T> e,
int count) {
do {
yield return e.Current;
count--;
} while (count > 0 && e.MoveNext());
}
+0
完美答案。但应该提供一个如何解决问题中的问题的例子。 – 2014-12-30 13:23:27
答
,那么这种方法是一种非常快速和有效的记忆方式。如果你真的只想要一个LINQ语句,那么不要介意。
private static T[][] SliceArray<T>(T[] source, int maxResultElements)
{
int numberOfArrays = source.Length/maxResultElements;
if (maxResultElements * numberOfArrays < source.Length)
numberOfArrays++;
T[][] target = new T[numberOfArrays][];
for (int index = 0; index < numberOfArrays; index++)
{
int elementsInThisArray = Math.Min(maxResultElements, source.Length - index * maxResultElements);
target[index] = new T[elementsInThisArray];
Array.Copy(source, index * maxResultElements, target[index], 0, elementsInThisArray);
}
return target;
}
答
int size = 3;
var results = testArray.Select((x, i) => new { Key = i/size, Value = x })
.GroupBy(x => x.Key, x => x.Value, (k, g) => g.ToArray())
.ToArray();
如果你不介意的结果被分类为IEnumerable<IEnumerable<T>>
而非T[][]
那么您完全可以忽略的ToArray
电话:
int size = 3;
var results = testArray.Select((x, i) => new { Key = i/size, Value = x })
.GroupBy(x => x.Key, x => x.Value);
答
您可以使用此分机
public static class Extension
{
private static IEnumerable<TList> Split<TList, T>(this TList value, int countOfEachPart) where TList : IEnumerable<T>
{
int cnt = value.Count()/countOfEachPart;
List<IEnumerable<T>> result = new List<IEnumerable<T>>();
for (int i = 0; i <= cnt; i++)
{
IEnumerable<T> newPart = value.Skip(i * countOfEachPart).Take(countOfEachPart).ToArray();
if (newPart.Any())
result.Add(newPart);
else
break;
}
return result.Cast<TList>();
}
public static IEnumerable<IDictionary<TKey, TValue>> Split<TKey, TValue>(this IDictionary<TKey, TValue> value, int countOfEachPart)
{
IEnumerable<Dictionary<TKey, TValue>> result = value.ToArray()
.Split(countOfEachPart)
.Select(p => p.ToDictionary(k => k.Key, v => v.Value));
return result;
}
public static IEnumerable<IList<T>> Split<T>(this IList<T> value, int countOfEachPart)
{
return value.Split<IList<T>, T>(countOfEachPart);
}
public static IEnumerable<T[]> Split<T>(this T[] value, int countOfEachPart)
{
return value.Split<T[], T>(countOfEachPart);
}
public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> value, int countOfEachPart)
{
return value.Split<IEnumerable<T>, T>(countOfEachPart);
}
}
+1,这种方法唯一的缺点是它被热切地评估。在返回单个元素之前,必须处理整个查询。 – JaredPar 2010-08-18 17:26:24
@JaredPar:点好了;然而,取决于收藏的大小或处理的性质,懒惰的评估可能被高估。即便如此,+1为您的解决方案提供了一个有效的懒惰方法。 – kbrimington 2010-08-18 17:30:08