Tuesday, April 01, 2008

Previously, a few of us held a discussion about the best way to concatinate a number of string array elements into a single string. You can find details here. Last week, I needed something a bit more general purpose. Came up with an extension method on IEnumerable that will accomplish this for any type.

public static string Fuse<TSource>(this IEnumerable<TSource> source, string separator)
{
    if (source is string[])
    {
        return string.Join(separator, source as string[]);
    }

    return source.Aggregate(new StringBuilder(),
        (sb, n) => sb.Length == 0 ? sb.Append(n) : sb.Append(separator).Append(n),
        sb => sb.ToString());
}

The method is optimized to use the string.Join method when the underlying type is a string. Join uses unsafe code and is very quick. Here are a few example uses:

string[] names = new string[] { "Andy", "Wayne", "Dina", };
string allNames = names.Fuse(", ");  // "Andy, Wayne, Dina"

int[] numbers = new int[] { 1, 2, 3, 4, 5, };
string allNumbers = numbers.Fuse(":"); // "1:2:3:4:5"

object[] objects = new object[] { 1, "ten", 5.5, true, false, };
string allObjects = objects.Fuse("/"); // "1/ten/5.5/True/False"

Andy | LINQ
Tuesday, April 01, 2008 6:55:53 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Thursday, February 14, 2008

My office mate Chad came up with yet an even better option. You need to be using 3.5 and include the System.Linq extension method namespace. It didn't perform quite as well but pretty close. Even more general purpose. Note that the default SequenceEqual method throws an exception when either operator is null so I handled those cases first.

bool Compare<T>(IEnumerable<T> left, IEnumerable<T> right)

{

    // handles the same array

    // handles both null

    if (left == right)

        return true;

 

    // fails when either are null

    if (left == null || right == null)

        return false;

 

    return left.SequenceEqual(right);

}

 

Andy | C# | LINQ
Thursday, February 14, 2008 3:02:02 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, February 04, 2008

In response to the previous posting. A few weeks ago, I would certainly have solved this the same way that you did in "OldSchool" with the exception of using IEnumerable<string>. Why limit your code to just string arrays? Now that we have LINQ, we can get pretty fancy! Technically one line within the method but I split it up to aid readability.

 

static void Main(string[] args)

{

    string[] names = new string[] { "Andy", "Marcy", "Cindy", "Jennifer", "Aaron" };

 

    Console.WriteLine(NewSchool(names));

}

 

static string NewSchool(IEnumerable<string> list)

{

    return list.Aggregate(new StringBuilder(),

        (sb, n) => sb.Length == 0 ? sb.Append(n) :

         sb.Append(",").Append(n),

        sb => sb.ToString());

}

 

And for even more fun, I built a simple test harness for each of these three methods. The test: 10000 itterations where I concatenate a string array that contains 8192 elements. Junior ran 36 minutes and 41.5 seconds*. OldSchool ran 8.453 seconds. NewSchool ran 9.484 seconds. NewSchool is likely slightly slower than OldSchool because of the use of the delegate. * I was only able to run 100 itterations on Junior which ran 22.015 seconds. I then extrapolated from there. The actual result would likely be even longer given its use of memory.

Andy | LINQ
Monday, February 04, 2008 1:23:04 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, January 25, 2008

I was recently working with an RDP settings file and its myriad of settings and corresponding lines. I couldn’t find what I needed so I thought it would be nice to sort the lines. I am sure there are utilities out there that can quickly sort a bunch of text lines but like most programmers, I thought it best that I develop my own solution. So I fired up VS and created a new Windows Forms project, added a standard TextBox and Button control to my form and wired up the following OnClick event:

private void ButtonSort_Click(object sender, EventArgs e)

{

    TextBoxMain.Lines = TextBoxMain.Lines

        .OrderBy(s => s)

        .ToArray();

}

Just too simple. Man I love LINQ!

LINQ | Andy
Friday, January 25, 2008 2:01:37 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  |