开发者

What is the shortest way to init a string array with empty strings?

开发者 https://www.devze.com 2023-01-27 06:45 出处:网络
Surprisingly for me new string[count]; is filled with nulls. So I came up with var emptyStrings = Enumerable.Range(0, count)

Surprisingly for me

new string[count];

is filled with nulls. So I came up with

var emptyStrings = Enumerable.Range(0, count)
    .Select(a => String.Empty)
    .ToArray();

which is very verbose. Isn't there a sho开发者_运维问答rcut?


You can use Enumerable.Repeat:

 string[] strings = Enumerable.Repeat(string.Empty, count).ToArray();

(But be aware that creating a string array of the correct size and looping will give better performance.)


Handling multiple dimensions

I had to work with a bunch of string arrays that had to be initialized to empty, some multi-dimensional. This was a bit of a pain so I created the following which you may find useful:

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;
    }
}

Then you can do something like:

class Foo
{
    public string[,] Data = new string[2,2].InitializeWithEmptyStrings();
}

Update - One method to handle arbitrary dimensions

I thought it would be fun to try and generalise this to combine creating the array and initializing it, using a general purpose method. It's not going to be as fast as the above, but it will handle arbitrary numbers of dimensions:

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 method requires the desired array as a generic parameter - use like so:

// this would create a string[2,3,4,2] initialized with empty strings
ArrayFactory.CreateArrayInitializedWithEmptyStrings<string[,,,]>(2,3,4,2);

Props to Ian Griffiths for his article series which was the source of the generalized CartesianProduct method.

Update 2

Here's a refined version of the Cartesian Product that used recursion to get the index combinations:

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;
        }
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消