【发布时间】:2010-11-24 15:32:19
【问题描述】:
令我惊讶
new string[count];
用nulls 填充。所以我想出了
var emptyStrings = Enumerable.Range(0, count)
.Select(a => String.Empty)
.ToArray();
这是非常冗长的。没有捷径吗?
【问题讨论】:
-
问题是为什么你需要默认的空字符串?
令我惊讶
new string[count];
用nulls 填充。所以我想出了
var emptyStrings = Enumerable.Range(0, count)
.Select(a => String.Empty)
.ToArray();
这是非常冗长的。没有捷径吗?
【问题讨论】:
你可以使用Enumerable.Repeat:
string[] strings = Enumerable.Repeat(string.Empty, count).ToArray();
(但请注意,创建正确大小的字符串数组并循环将提供更好的性能。)
【讨论】:
Enumerable.Repeat多几个字符。
我不得不处理一堆必须初始化为空的字符串数组,有些是多维的。这有点痛苦,所以我创建了以下内容,您可能会觉得有用:
public static class StringArrayExtensions
{
public static string[] InitializeWithEmptyStrings(this string[] source)
{
// the jitter will hoist source.Length out of the loop automatically here
for(int i = 0; i < source.Length; i++)
source[i] = string.Empty;
return source;
}
public static string[,] InitializeWithEmptyStrings(this string[,] source)
{
var len0 = source.GetLength(0);
var len1 = source.GetLength(1);
for (int i = 0; i < len0; i++)
for (int j = 0; j < len1; j++)
source[i,j] = string.Empty;
return source;
}
}
然后你可以这样做:
class Foo
{
public string[,] Data = new string[2,2].InitializeWithEmptyStrings();
}
我认为尝试将其推广到结合使用通用方法创建数组和初始化它会很有趣。它不会像上面那样快,但它可以处理任意数量的维度:
public static class ArrayFactory
{
public static TArrayType CreateArrayInitializedWithEmptyStrings<TArrayType>(
params int[] dimensionLengths) where TArrayType : class
{
var dimensions = dimensionLengths.Select(l => Enumerable.Range(0, l));
var array = Array.CreateInstance(typeof(string), dimensionLengths);
foreach (var indices in CartesianProduct(dimensions))
array.SetValue(string.Empty, indices.ToArray());
return (array as TArrayType);
}
private static IEnumerable<IEnumerable<T>> CartesianProduct<T>(
IEnumerable<IEnumerable<T>> dimensions)
{
return dimensions.Aggregate(
(IEnumerable<IEnumerable<T>>)new T[][] { new T[0] },
(acc, input) =>
from prevDimension in acc
from item in input
select prevDimension.Concat(new T[] { item }));
}
}
此方法需要所需的数组作为通用参数 - 像这样使用:
// this would create a string[2,3,4,2] initialized with empty strings
ArrayFactory.CreateArrayInitializedWithEmptyStrings<string[,,,]>(2,3,4,2);
为 Ian Griffiths 的 article series 提供支持,这是广义 CartesianProduct 方法的来源。
这是笛卡尔积的精炼版本,它使用递归来获取索引组合:
public static class ArrayFactory
{
public static TArrayType CreateArrayInitializedWithEmptyStrings<TArrayType>(
params int[] dimensionLengths) where TArrayType : class
{
var array = Array.CreateInstance(typeof(string), dimensionLengths);
foreach (var indices in CartesianProduct(dimensionLengths))
array.SetValue(string.Empty, indices.ToArray());
return (array as TArrayType);
}
private static IEnumerable<IEnumerable<int>> CartesianProduct(params int[] dimensions)
{
return CartesianProductImpl(Enumerable.Empty<int>(), dimensions);
IEnumerable<IEnumerable<int>> CartesianProductImpl(
IEnumerable<int> leftIndices, params int[] dims)
{
if (dims.Length == 0)
{
yield return leftIndices;
yield break;
}
for (int i = 0; i < dims[0]; i++)
foreach (var elem in CartesianProductImpl(leftIndices.Concat(new[] { i }),
dims.Skip(1).ToArray()))
yield return elem;
}
}
}
【讨论】: