Best linq questions in December 2010

Is there a C# unit test framework that supports arbitrary expressions rather than a limited set of adhoc methods?

20 votes

Basically NUnit, xUnit, MbUnit, MsTest and the like have methods similar to the following:

Assert.IsGreater(a,b)
//or, a little more discoverable
Assert.That(a, Is.GreaterThan(b))

However, there are a limited number of such comparison operators built-in; and they duplicate the languages operators needlessly. When I want anything even slightly complex, such as...

Assert.That(a.SequenceEquals(b))

I'm often either left digging through the manual to find the equivalent of the expression in NUnit-speak, or am forced to fall-back to plain boolean assertions with less helpful error messages.

C#, however, integrates well with arbitrary Expressions - so it should be possible to have a method with the following signature:

void That(Expression<Func<bool>> expr);

Such a method could be used to both execute the test (i.e. validate the assertion) and to also provide less-opaque diagnostics in case of test failure; after all, an expression can be rendered to pseudo-code to indicate which expression failed; and with some effort, you could even evaluate failing expressions intelligently to give some clue of the value of subexpressions.

For example:

Assert.That(()=> a == b);//could inspect expression and print a and b
Assert.That(()=> a < b && b < c);
//could mention the values of "a<b" and "b<c" and/or list the values of a, b, and c.

At a minimum, it would make the use of a parallel language for expressions unnecessary, and in some cases it might make failure messages more useful.

Does such a thing exist?

Edit: After trying (and liking!) Power Assert, I ended up reimplementing it to address several limitations. My variant of this is published as ExpressionToCode; see my answer below for a list of improvements.

(Original Poster here)

I love PowerAssert.NET's simple syntax and messages, but the C# it produces has many issues. In particular, it doesn't support several expression features, and it doesn't add parentheses where required by operator precedence/associativity. After fixing a few bugs (and reporting them to the author) I found it'd be simpler to fix with a different approach, and to reimplement it from scratch.

The usage is similar:

PAssert.That(()=>
    Enumerable.Range(0,1000).ToDictionary(i=>"n"+i)["n3"].ToString()
    == (3.5).ToString()
);

Outputs:

PAssert.That failed for:

Enumerable.Range(0, 1000).ToDictionary(i => "n" + (object)i)["n3"].ToString() == 3.5.ToString()
             |                 |                            |         |        |        |
             |                 |                            |         |        |        "3.5"
             |                 |                            |         |        false
             |                 |                            |         "3"
             |                 |                            3
             |                 {[n0, 0], [n1, 1], [n2, 2], [n3, 3], [n4, 4], [n5, 5], [n6, 6], [n7, 7], [n8, 8], [n9, 9], ...}
             {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...}

Improvements over PowerAssert.NET:

  • Supports static field and property access
  • Supports more operators, such as logical and bitwise negation.
  • Recognizes C# indexer use (e.g. dict["mykey"]==3)
  • Adds parentheses where required by operator precedence and associativity (e.g. () => x - (a - b) + x * (a + b) is correctly regenerated)
  • Generates valid numeric and other constant literals including escapes and suffixes as appropriate for the expression type (e.g. 1m + (decimal)Math.Sqrt(1.41))
  • Supports C# syntactic sugar for object initializers, object member initializers, list initializers, extension methods, amongst other things.
  • Uses the same spacing rules Visual Studio does by default.
  • Supports nested Lambdas
  • Expands generic type instances into normal C#; e.g. Func<int, bool>
  • Supports several expression tree constructs not yet used by C# 4.0 embedded expressions.

The resultant project (with unit tests) is hosted in google code under the name ExpressionToCode - I hope it's useful to others.

MasterMind scoring algorithm in C# using LINQ

18 votes

I'm looking for an elegant way to compute the score of a guess in the MasterMind game in C#, preferably using LINQ.

In MasterMind, the codemaker generates a secret code of 4 digits using the digits 1 through 6. A digit may be used more than once. As an example, the secret code is:

int[] secret = { 1, 2, 3, 1 };

The codebreaker tries to break the secret code by presenting a guess. In this example, the guess is:

int[] guess  = { 1, 1, 2, 2 };

(Both code and guess are now stored in an array, but other collection types are okay too).

The codemaker then "scores" this guess by announcing the number of "blacks" and "whites". A black is awarded for each digit from the guess which is correct in both value and position. A white is awarded for each correct digit placed in the wrong position. In this example, the score is 1 black (for the "1" in position 1) and 2 whites (for the "1" and "2" in positions 2 and 3).

Back to the question: I'm looking for an elegant way to compute the score of a guess in C#, preferably using LINQ. So far, I've come up with a statement that computes the number of blacks:

int blacks = new int[] { 0, 1, 2, 3 }.Count(i => (guess[i] == secret[i]));

I was going to proceed along the lines that the number of whites is the total number of matches (3) minus the number of blacks. So I tried:

int whites = guess.Intersect(secret).Count() - blacks;

But, alas, IEnumerable.Intersect() produces { 1, 2 } instead of { 1, 1, 2 }, because it looks at distinct digits only. So it computes whites = 1 instead of 2.

I cannot come up with another way of computing "whites", except from using "C" style nested loops. Can you? Preferably using LINQ - I like the way an algorithm can be expressed in code using LINQ. Execution speed is not really an issue.

var black = guess
        .Zip(secret, (g, s) => g == s)
        .Count(z => z);

var white = guess
        .Intersect(secret)
        .Sum(c =>
            System.Math.Min(
                secret.Count(x => x == c),
                guess.Count(x => x == c))) - black;

Given:

int[] secret = { 1, 2, 3, 1 };
int[] guess  = { 1, 1, 2, 2 };

Then:

black == 1 && white == 2

Can I split an IEnumerable into two by a boolean criteria without two queries?

12 votes

Folks,

Is it possible to split an IEnumerable into two IEnumerables using LINQ and only a single query/linq statement? In this way, I would avoid iterating through the IEnumerable twice. For example, is it possible to combine the last two statements below so allValues is only traversed once?

IEnumerable<MyObj> allValues = ...
List<MyObj> trues = allValues.Where( val => val.SomeProp ).ToList();
List<MyObj> falses = allValues.Where( val => !val.SomeProp ).ToList();

You can use this:

var groups = allValues.GroupBy(val => val.SomeProp);

To force immediate evaluation like in your example:

var groups = allValues.GroupBy(val => val.SomeProp)
                      .ToDictionary(g => g.Key, g => g.ToList());
List<MyObj> trues = groups[true];
List<MyObj> falses = groups[false];

Scala collection-like SQL support as in LINQ

10 votes

As far as I understand the only thing LINQ supports, which Scala currently doesn't with its collection library, is the integration with a SQL Database.

As far as I understand LINQ can "accumulate" various operations and can give "the whole" statement to the database when queried to process it there, preventing that a simple SELECT first copies the whole table into data structures of the VM.

If I'm wrong, I would be happy to be corrected.

If not, what is necessary to support the same in Scala?

Wouldn't it possible to write a library which implements the collection interface, but doesn't have any data structures backing it but a String which gets assembled with following collection into the required Database statement?

Or am I completely wrong with my observations?

As the author of ScalaQuery, I don't have much to add to Stilgar's explanation. The part of LINQ which is missing in Scala is indeed the expression trees. That is the reason why ScalaQuery performs all its computations on Column and Table types instead of the basic types of those entities.

You declare a table as a Table object with a projection (tuple) of its columns, e.g.:

class User extends Table[(Int, String)] {
  def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def name = column[String]("name")
  def * = id ~ name
}

User.id and User.name are now of type Column[Int] and Column[String] respectively. All computations are performed in the Query monad (which is a more natural representation of database queries than the SQL statements that have to be created from it). Take the following query:

val q = for(u <- User if u.id < 5) yield u.name

After some implicit conversions and desugaring this translates to:

val q:Query[String] =
  Query[User.type](User).filter(u => u.id < ConstColumn[Int](5)).map(u => u.name)

The filter and map methods do not have to inspect their arguments as expression trees in order to build the query, they just run them. As you can see from the types, what looks superficially like "u.id:Int < 5:Int" is actually "u.id:Column[Int] < u.id:Column[Int]". Running this expression results in a query AST like Operator.Relational("<", NamedColumn("user", "id"), ConstColumn(5)). Similarly, the "filter" and "map" methods of the Query monad do not actually perform filtering and mapping but instead build up an AST that describes these operations.

The QueryBuilder then uses this AST to construct the actual SQL statement for the database (with a DBMS-specific syntax).

An alternative approach has been taken by ScalaQL which uses a compiler plugin to work directly with expression trees, ensure that they only contain the language subset which is allowed in database queries, and construct the queries statically.

Convert SQL to LINQ to SQL

6 votes

Hi

I have the SQL query

with c as (
  select  categoryId,parentId, name,0 as [level]
  from task_Category b 
  where b.parentId is null
    union all
  select b.categoryId,b.parentId,b.name,[level] + 1
  from task_Category b join c on b.parentId = 
    c.categoryId)
select name,[level],categoryId,parentId 
  as item 
from c

and I want to convert it to LINQ to SQL, yet my LINQ skills are not there yet. Could someone please help me convert this. It's the with and union statements that are making this a bit more complex for me.

Any help appreciated.

LINQ-to-SQL only supports basic queries; CTE and recursion are not included in this. Therefore, here's my high-tech translation to LINQ-to-SQL:

var data = ctx.ExecuteQuery<MyStub>(@"
with c as (
  select  categoryId,parentId, name,0 as [level]
  from task_Category b 
  where b.parentId is null
    union all
  select b.categoryId,b.parentId,b.name,[level] + 1
  from task_Category b join c on b.parentId = 
    c.categoryId)
select name,[level],categoryId,parentId 
  as item 
from c").ToList();

with

class MyStub {
    public string name {get;set;}
    public int level {get;set;}
    public int categoryId {get;set;}
    public int parentId {get;set;}
}

LINQ to XML via C#

4 votes

Hello,

I'm new to LINQ. I understand it's purpose. But I can't quite figure it out. I have an XML set that looks like the following:

<Results>
  <Result>
    <ID>1</ID>
    <Name>John Smith</Name>
    <EmailAddress>john@example.com</EmailAddress>
  </Result>
  <Result>
    <ID>2</ID>
    <Name>Bill Young</Name>
    <EmailAddress>bill@example.com</EmailAddress>
  </Result>
</Results>

I have loaded this XML into an XDocument as such:

string xmlText = GetXML();
XDocument xml = XDocument.Parse(xmlText);

Now, I'm trying to get the results into POCO format. In an effort to do this, I'm currently using:

var objects = from results in xml.Descendants("Results")
              select new Results
              // I'm stuck

How do I get a collection of Result elements via LINQ? I'm particularly confused about navigating the XML structure at this point in my code.

Thank you!

This will return a IEnumerable of anonymous class:

var q = from result in xml.Descendants
        select new
        {
            ID = result.Descendants("ID"),
            Name= result.Descendants("Name"),
            EmailAddress= result.Descendants("EmailAddress")
        };

or if you have defined class `Result, e.g.:

class Result
{
    public ID { get; set; }
    public Name { get; set; }
    public EmailAddress { get; set; }
}

then:

var q = from result in xml.Descendants
        select new Result
        {
            ID = result.Descendants("ID"),
            Name = result.Descendants("Name"),
            EmailAddress = result.Descendants("EmailAddress")
        };

(returns IEnumerable<Result>)