KBD

Keith Devens .com

Saturday, September 6, 2008 Flag waving
Crying is all right in its way while it lasts. But you have to stop sooner or later, and then... – C.S. Lewis (The Silver Chair, ch 2)

Archive: July 24, 2008

← July 23, 2008July 25, 2008 →

Daily link icon Thursday, July 24, 2008

  1. Second p0st: PHP hackery: quick and dirty anonymous objects. Eew.

       (0) Tags: [PHP]
  2. SitePen Blog » window.name Transport (via Keith and Simon). To read.

       (0) Tags: [Javascript, To Read]
  3. LINQ to Objects - 5 Minute Overview - Hooked on LINQ. Decent tutorial. Has examples of grouping and joins.

       (0) Tags: [C#, LINQ]
  4. Download LINQPad (via).

       (0) Tags: [LINQ, Software, SQL]
  5. C# 3.0: The Evolution Of LINQ And Its Impact On The Design Of C# (via). Very interesting explanation of how LINQ came about.

       (0) Tags: [C#, LINQ]
  6. New "Orcas" Language Feature: Extension Methods - ScottGu's Blog. Very informative post.

    Edit: He also covers C# 3's query syntax (i.e. LINQ).

       (0) Tags: [C#, LINQ]
  7. "ScrewTurn Wiki is a fast, powerful and simple ASP.NET wiki engine, installs in a matter of minutes and it's available in different packages, fitting every need. It's even free and opensource."

       (0) Tags: [Software, Wiki]

Joining together the results of a LINQ query into a string

Say you want to search a string with a regular expression and return all the matches concatenated together, using LINQ:

var str = "some string";
var matches = Regex.Matches(str, @"REGEX");

Three ways to concatenate:

Using String.Join (simplest):

var foo = String.Join("", (from Match match in result select match.Value).ToArray());

Using an accumulator:

var foo = (from Match match in matches select match.Value)
    .Aggregate(new StringBuilder(), (sb, s) => sb.Append(s)).ToString();

Using a loop:

var sb = new StringBuilder();
foreach (var s in (from Match match in result select match.Value)){
    sb.Append(s);
}
var foo = sb.ToString();

First seems most concise, and it's easier to specify a join character with. Apparently there's no way to massage an IEnumerable(T) into a String.Join, so unfortunately you need to pass it an array, which makes the IEnumerable fill out all its values into an array (so it can't be lazy), and then String.Join makes another pass over that array and copies the values into a string. So it uses double the space and double the time.

The second is more obscure, but only makes one pass over the result, though it's harder to specify a join character if desired.

The third is presumably most efficient, but it's more verbose.

In conclusion, there should be a String.Join(IEnumerable<T>).

Edit: Though it's impossible to define a "static" extension method (like, another variation of String.Join), you can define a Join method on IEnumerable like so:

static class Extentions{
    public static string Join(this IEnumerable source, string separator){
        var sb = new StringBuilder();
        bool first = true;
        foreach(var foo in source){
            if(!first)
              sb.Append(separator);

            sb.Append(foo.ToString());
            first = false;
        }
        return sb.ToString();
    }
}

The first example above now becomes:

var foo = (from Match match in result select match.Value).Join("");

or even more concisely:

var foo = Regex.Matches(str, @"REGEX").Join("");
// (apparently the ToString on a Match object returns its Value)

Very cool.

Note: Works with custom ToString()s as expected:

class Custom{
    public string Value { get; set; }
    public override string ToString(){
        return "VALUE: "+Value;
    }
}
var list = new List<Custom> {
    new Custom { Value = "one" },
    new Custom { Value = "two" }
};

Console.WriteLine(list.Join(", "));

prints "VALUE: one, VALUE: two" as expected.

Final note: I would have used FirstOrDefault in my Join extension method instead of a first boolean, but the example of the regular expression object was chosen because it's not a generic, so I can't use IEnumerable<T>, only IEnumerable.

  1. <3 Delphi Basics

       (0) Tags: [Delphi]
← July 23, 2008July 25, 2008 →
September 2008
SunMonTueWedThuFriSat
 123456
78910111213
14151617181920
21222324252627
282930 



RSS feed RSS feed for Keith's Weblog
Atom feed Atom feed for Keith's Weblog
Weblog archive
Recent comments
  on 5 posts

Recent comments XML

new⇒I hate ASP.NET

CF, why pick that piece of trash?​Cold Confusion. Is it finally​really a OO...

ColdConfusion: Sep 5, 8:36pm

Maps of Iraq

This is for Linda, I will be​visiting that site some time in the​near futur...

Bob: Sep 5, 1:20pm

Girls, please don't get breast implants

Well alright I just read my above​comment and I wanted to add​this...I shou...

76.66.140.8: Sep 4, 7:31pm

Spider solitaire

I don't think the question was​necessarily if there are unbeatable​games.  ...

Jared: Sep 4, 12:44pm

Convert Pantone Colors to RGB and Hex - Color Conversion Chart

The colors on those website don't​seem to relate to the pantone data​we hav...

blah: Sep 3, 10:12am

Generated in about 0.09s.

(Used 7 db queries)

mobile phone