What good is .SELECT in LINQ anyway? seems useless compared to.where

R

RayLopez99

Please examine the below code. Kindly explain why .Select does not
work except to produce a 'bool' and further, how can you extract which
member is true/false?

This is the complete code (Jon).

I used .Where to get the information I need (namely, finding a maximum
point in an array of Points, then finding all points less than this
maximum point). Why could not I use .Select to do this? Select seems
useless.

RL

//Windows Forms so for points use using System.Windows.Forms; and
using.System.Linq;
/// find the maximum Point in an array of Points, then find all points
that are less than this maximum point.


Point[] PtsInArray = { new Point(10, 10), new Point(20, 1), new Point
(1,2), new Point(2,2) };

int Max = PtsInArray.Max(ImplicitDummyVar =>
ImplicitDummyVar.X + ImplicitDummyVar.Y);

int Min = PtsInArray.Min(x => x.X + x.Y);

Console.WriteLine("Here are the Max, Min: Max= {0}, Min=
{1}", Max, Min);

// IEnumerable<Point> i1 = PtsInArray.Select(x => (x.X + x.Y) >
Min); //won't compile, why?

var MinPtsArr2 = PtsInArray.Select(x => (x.X + x.Y) >
Min);
foreach (var i2 in MinPtsArr2)
{
Console.WriteLine("data is: {0}", i2);

}

IEnumerable<Point> SomePtsArr3 = PtsInArray.Where(x => (x.X
+ x.Y) < Max);
foreach (Point p in SomePtsArr3)
{
Console.WriteLine("Works, point p less than {0}, is:
{1},{2}", Max, p.X, p.Y);
}

/* //output
*
* Here are the Max, Min: Max= 21, Min= 3
data is: True
data is: True
data is: False
data is: True
Works, point p less than 21, is: 10,10
Works, point p less than 21, is: 1,2
Works, point p less than 21, is: 2,2
*
*
* */
 
A

Arne Vajhøj

RayLopez99 said:
This is the complete code (Jon).
//Windows Forms so for points use using System.Windows.Forms; and
using.System.Linq;
/// find the maximum Point in an array of Points, then find all points
that are less than this maximum point.


Point[] PtsInArray = { new Point(10, 10), new Point(20, 1), new Point
(1,2), new Point(2,2) };

int Max = PtsInArray.Max(ImplicitDummyVar =>
ImplicitDummyVar.X + ImplicitDummyVar.Y);

int Min = PtsInArray.Min(x => x.X + x.Y);

Console.WriteLine("Here are the Max, Min: Max= {0}, Min=
{1}", Max, Min);

If this is your complete code, then one of your problems is
the lack of class and method.

Arne
 
A

Arne Vajhøj

RayLopez99 said:
Point[] PtsInArray = { new Point(10, 10), new Point(20, 1), new Point
(1,2), new Point(2,2) };

int Max = PtsInArray.Max(ImplicitDummyVar =>
ImplicitDummyVar.X + ImplicitDummyVar.Y);

int Min = PtsInArray.Min(x => x.X + x.Y);

Console.WriteLine("Here are the Max, Min: Max= {0}, Min=
{1}", Max, Min);

// IEnumerable<Point> i1 = PtsInArray.Select(x => (x.X + x.Y) >
Min); //won't compile, why?

How could it compile ?

You can not assign an IEnumerable<bool> to a
IEnumerable<Point>.

You may find the following illustrative:

using System;
using System.Linq;
using System.Drawing;

namespace E
{
public class Program
{
public static void Main(string[] args)
{
Point[] PtsInArray = { new Point(10, 10), new Point(20, 1),
new Point(1,2), new Point(2,2) };
int Min = PtsInArray.Min(p => p.X + p.Y);
Console.WriteLine(PtsInArray.Select(x => (x.X + x.Y) >
Min).First().GetType().Name);
Console.WriteLine(PtsInArray.Select(x => (x.X + x.Y) > Min
? 1 : 0).First().GetType().Name);
Console.WriteLine(PtsInArray.Select(x => (x.X + x.Y) > Min
? ">" : "<").First().GetType().Name);
Console.ReadKey();
}
}
}

Arne
 
A

Arne Vajhøj

RayLopez99 said:
Why could not I use .Select to do this? Select seems
useless.

This is actually quite like SQL. Where restricts what rows (objects
in LINQ for objects) you want. Select allow you to specify the
columns in the query output (can return a different type in LINQ
for objects). Two completely different things.

And since Select is used in 50-75% of all LINQ, then it must somewhat
be useful.

Arne
 
G

Göran Andersson

RayLopez99 said:
Please examine the below code. Kindly explain why .Select does not
work except to produce a 'bool' and further, how can you extract which
member is true/false?

This is the complete code (Jon).

I used .Where to get the information I need (namely, finding a maximum
point in an array of Points, then finding all points less than this
maximum point). Why could not I use .Select to do this? Select seems
useless.

The Select method is used to specify what is going to be returned for
each selected record, it's not used to specify which records to select.

Of course it seems useless if you don't know how to use it...
 
A

Anthony Jones

RayLopez99 said:
// IEnumerable<Point> i1 = PtsInArray.Select(x => (x.X + x.Y) >
Min); //won't compile, why?

Select specifies the item type to return not which items to return. LINQ
attempts to borrow semantics we are already familiar using from SQL.
SELECT in SQL specifies the set of fields to return _not_ which rows from
the source to return.

In LINQ speak we refer to the 'set of fields' as a Projection. The purpose
of Select in LINQ is to take the input type and return a different type,
quite often new anonymous type. You are correct that in cases where the
type you want is the input type Select is superflous, Where is method that
does what you intend. If you were use the LINQ syntax any such superflous
Select would be eliminated from the final code.

Hence in the code above your call to Select returns an IEnumerable<bool>
which fails to assign to IEnumerable said:
var MinPtsArr2 = PtsInArray.Select(x => (x.X + x.Y) >
Min);

This line works since MinPtsArr2 gets the type IEnumerable<bool>
 
R

RayLopez99

In LINQ speak we refer to the 'set of fields' as a Projection.  The purpose
of Select in LINQ is to take the input type and return a different type,
quite often new anonymous type.  You are correct that in cases where the
type you want is the input type Select is superflous, Where is method that
does what you intend.   If you were use the LINQ syntax any such superflous
Select would be eliminated from the final code.

Thanks, this explanation made the most sense to me.

RL
 
D

DabblerNL

Well, Anthony's reply wat certainly the least offensive...

Below an example of how Where en Select cooperate and are both useful:

IEnumerable<int> SomePtsArr3 = PtsInArray.Where(x => (x.X+ x.Y) < Max)

..Select(x=>x.X);
foreach (int x in SomePtsArr3)
{
Console.WriteLine("Works, X coordinate of point less than
{0}, is:
{1},{2}", Max, x;
}

personally I prefer to code the above as:
IEnumerable<int> xCoordinates=from point in PtsInArray
where point.X+point.Y<Max
select point.X;
 
P

Peter Morris

And since Select is used in 50-75% of all LINQ, then it must somewhat
be useful.

I thought it was used in 100% of LINQ, because it acts as a "Now execute the
query" trigger?
 
G

Göran Andersson

Peter said:
I thought it was used in 100% of LINQ, because it acts as a "Now execute
the query" trigger?

No, not 100%, as a query may end with either a select or a group by.

Also, the select (or group by) is only required for the LINQ syntax. If
you call the extension methods directly you can for example just use the
Where method and get it's return value without running it through the
Select method.
 
J

Jon Skeet [C# MVP]

RayLopez99 said:
Please examine the below code. Kindly explain why .Select does not
work except to produce a 'bool' and further, how can you extract which
member is true/false?

This is the complete code (Jon).

No, it's not.

Others have answered your question, but please don't claim code is
complete when it's not. It's very easy to test this:

1) Open Notepad
2) Copy the code from the newsgroup post (or whatever)
3) Paste into Notepad
4) Save the file
5) Run "csc Test.cs" from the command line.

If it compiles and then runs (potentially with an error, if that's the
point of the post) then it's complete. Otherwise, it's probably not.
Occasionally you may *need* more than one source file (e.g. to
demonstrate partial types) or an extra file (e.g. an XML file to read)
but 90% of the time you can get away with just one file.

Please see http://pobox.com/~skeet/csharp/complete.html and
http://pobox.com/~skeet/csharp/incomplete.html for more on this. It's
really not hard to post complete examples, and it makes it a lot
simpler for others to help you.
 
A

Arne Vajhøj

Peter said:
I thought it was used in 100% of LINQ, because it acts as a "Now execute
the query" trigger?

The percentage depends lot of whether you only count LINQ syntax
or also include all the supporting methods in System.Linq.

BTW, I assume that the use of Select will not always get
the query executed.

Arne
 
R

RayLopez99

Please seehttp://pobox.com/~skeet/csharp/complete.htmlandhttp://pobox.com/~skeet/csharp/incomplete.htmlfor more on this. It's
really not hard to post complete examples, and it makes it a lot
simpler for others to help you.

Is this that Snippey tool you keep pushing Jon? I know it's your
pride and joy, as you keep mentioning it in your book. Too much
bother. Anybody with half a brain can cut and paste my code and make
it work with a few tweeks.

But as partial classes become more common, perhaps your tool has some
value, if it somehow makes copying code easier.

RL
 
R

RayLopez99

Well, Anthony's reply wat certainly the least offensive...

Below an example of how Where en Select cooperate and are both useful:

IEnumerable<int> SomePtsArr3 = PtsInArray.Where(x => (x.X+ x.Y) < Max)

.Select(x=>x.X);
           foreach (int x in SomePtsArr3)
           {
               Console.WriteLine("Works,  X coordinate of point less than
{0}, is:
{1},{2}", Max, x;
           }

personally I prefer to code the above as:
IEnumerable<int> xCoordinates=from point in PtsInArray
                                                where point.X+point.Y<Max
                                                select point.X;

Thanks Dabbler! I appreciate this and put it into my form file. I
can see where adding an .OrderbyDescending or whatnot will then allow
you to sort point X afterwards, etc. I will experiment with this
later. Before I was using Linq on successive enumerations, but this
chaining technique is much cleaner.

RL
 
J

Jon Skeet [C# MVP]

RayLopez99 said:
Is this that Snippey tool you keep pushing Jon?

No, although that would potentially make life slightly easier. That
page has been up (and referenced) for years before the book was
written. It's just standard good practice, IMO. (I really don't "keep
pushing it" btw. Yes, there was a blog post about the Reflector add-in
recently, but that's about it.)
I know it's your pride and joy, as you keep mentioning it in your
book. Too much bother.

It's far from my pride and joy. It's got a butt-ugly user interface,
and basically does just about what it needs to, and that's all. It was
developed for a very specific purpose (the book).

Compare this with LINQPad, which has clearly had a lot more effort put
into it.
Anybody with half a brain can cut and paste my
code and make it work with a few tweeks.

But why should they have to? The person who is presenting the code is
generally going to benefit from the response, so in my view they should
put the effort in. That's more efficient too - why get (say) 10 people
to all do the same work rather than do it once yourself?

Next point: by coming up with a short but complete program, people
often find the answer to the question they were going to ask anyway.
The act of honing a problem down to its core is frequently enough to
shine a light on it. This is a good thing to learn - solving your own
problems is an important skill.

Basically, if someone expects me (and other posters) to put some time
into helping them or explaining something, I expect *them* to put a bit
of effort into presenting the problem as clearly as possible. Not doing
so shows a lack of respect, in my view.
But as partial classes become more common, perhaps your tool has some
value, if it somehow makes copying code easier.

I can't see how Snippy would particularly help with that.
 
P

proxyuser

Is this that Snippey tool you keep pushing Jon? I know it's your
pride and joy, as you keep mentioning it in your book. Too much
bother. Anybody with half a brain can cut and paste my code and make
it work with a few tweeks.

Question: who is this guy and why is everyone continuing to put up with him?
 
N

Nicholas Paldino [.NET/C# MVP]

Peter,

The "now execute the query trigger" is when you call the methods on the
IEnuemrable interface implementation (specifically, MoveNext). This is what
causes the query to be executed.

Select is simply the method by which projections are generated.
 
R

RayLopez99

I tried to compile the below code you posted in your website and it
failed. I think something needs to be commented out, like the first
four lines.

Oh well...do as i say, not as I do.

RL

I have read that C# passes objects by reference. This doesn't seem to
be
the case given the program below. I expected it to print "second", but
it
prints "first".
Can anyone explain this behaviour?

using System;

public class Test
{
static void Main()
{
string x = "first";
ChangeString (x);
Console.WriteLine (x);
}

static void ChangeString (string y)
{
y = "second";
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top