tags:

views:

209

answers:

4

I have the following linq query:

 var files = (from d in new DirectoryInfo(@"c:\program files").GetDirectories()
                         where d.GetFiles().Count() > 10
                         where d.GetFiles().Count() < 100
                         select d
             );

However, as you can see above, I am calling d.GetFiles().Count() twice, is this where the concept of the => operator comes in handy.

Using the syntax from jdehaan, why can't I do it directly like this:

var files = (from d in new DirectoryInfo(@"c:\program files").GetDirectories()
                         where(x => x.GetFiles().Count() > 10) &&
                         (x.GetFiles().Count() < 100))
                         select d
             );

I know the above is stupid because I could just do my original query with d.GetFiles().Count(), but I am curious on the difference between using Where as opposed to the keyword where.

+14  A: 

Use let to assign within the query, like this

var files = (from d in new DirectoryInfo(@"c:\program files").GetDirectories()
   let f = d.GetFiles().Count()
   where f > 10
   where f < 100
   select d
);

As Reed Copsey points out you can merge the two where clauses using &&.

Also, since GetFiles returns an array you can use the Length property instead of the Count method.

  var files = (from d in new DirectoryInfo(@"c:\program files").GetDirectories()
     let f = d.GetFiles().Length
     where f > 10 && f < 100
     select d
  );
Brian Rasmussen
+1 not using lambdas, but still: excellent answer!
marc_s
You can also combine the two where statements, which may be more readable.
Reed Copsey
Nice. That works. Curious, is this the only way to do it?
Xaisoft
@Reed: Sure, good point, I was just addressing the specific question.
Brian Rasmussen
@Xaisoft As for this being the only way, no (see my alternate answer below.)
Paul Williams
+5  A: 

Lambda expressions will not help here, but the let keyword may...

var files = from d in new DirectoryInfo(@"c:\program files").GetDirectories()
                  let c = d.GetFiles().Count()
                  where c > 10 && c < 100
                  select d;
Reed Copsey
Thanks as well again for the help on linq. What was I thinking when I said lambda expression, lol.
Xaisoft
Technically, you can do this using a lambda, but it requires a nested select (which is what let does for you), so "let" makes life much easier.
Reed Copsey
+2  A: 

With lambda expressions it would look like this:

var files = new DirectoryInfo(@"c:\program files").GetDirectories().
    Where(x => (x.GetFiles().Count() > 10) && (x.GetFiles().Count() < 100));

You also call the GetFiles() twice. The lambda expressions don't help solving it.

EDIT: Beside being ugly, it is really inefficient, prefer the let solution presented in the other answers, this answer was meant to show what it looks like written using lambda expressions.

Have a look at "Paul Williams"'s answer, he showed how to reach the same thing with lambda expressions in a better and nicer way that is semantically equivalent to the let solution.

jdehaan
Ok, so I guess I wasn't to far off with wanting to use lambda expressions. I am still a little confused on the purpose of the lambda expression. The only difference I see is that there is no "from d in" specified in the query.
Xaisoft
We can do better than this: it still calls .Count() twice.
Joel Coehoorn
I was not meant to be a solution but more showing what it would look like if done that (ugly) way. Don't vote me too much up!! :-)
jdehaan
You actually want me to take my vote back, lol. I appreciate the alternate solutions. They don't necessarily have to be exactly what I asked for.
Xaisoft
@Joel Coehoorn, First after having read the answer from Paul Williams, I understood what you meant! Thanks for the hint, but I was too slow ;-)
jdehaan
+2  A: 

The answer involving the "let" keyword is probably what you will want to use.

I am providing this alternate answer to show you how "=>" could be used to accomplish the same thing.

First, make sure you are using System.Linq;

var files = new DirectoryInfo(@"c:\program files").GetDirectories().Where(d =>
  {
    int c = d.GetFiles().Count();
    return c > 10 && c < 100;
  });

As you can see, lambda expressions aren't a "better" solution in this case, just different.

Paul Williams
Thanks. Look at my updated post. What is the difference between Where as opposed to using the where keyword.
Xaisoft
Good point that helps me reminding of the anonymous methods! +1
jdehaan
I am assuming that the return behaves differently than a return in a regular method. Am I correct? This doesn't return from the query, it just reduces the result set stored in files. Is my understanding of it correct?
Xaisoft
In this case, we are returning a value from the lambda expression (lambdas are just functions without names.)Where() applies the lambda function to each item in the collection of directories and if the function returns true, that directory is included.
Paul Williams