Solved

# yet another LINQ question

Posted on 2014-07-14
193 Views
Hi, LINQ is hard .....

My entire test application is below

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;

namespace ConsoleApplication3
{
class Program
{
private Single getAverageX(List<PointF> points)
{
Single average = (from point in points
select point.X
).Average();

return average;
}

public void TestLinq()
{
List<PointF> points = new List<PointF> { new PointF(1f, 2f), new PointF(3f, 4f) };
Console.WriteLine(getAverageX(points));
points = new List<PointF> { new PointF(1f, 2f) };
Console.WriteLine(getAverageX(points));
points = new List<PointF>();
Console.WriteLine(getAverageX(points));
}

static void Main(string[] args)
{
Program p = new Program();
p.TestLinq();
}
}
}

It almost works !

The first time getAverageX is invoked, it calculates the average of 1 and 3 and returns 2. Correct.
The second time getAverageX is invoked, it calculates the average of 1 and no other numbers and returns 1. Correct.
The third time getAverageX is invoked, it errors. I need to provide a default value of 0 to get it to work.

LINQ has this FirstOrDefault method that I think I need to use. But I can't quite get there. I know this is simple, I really do, I just can't get there.

Thank you again experts for reading my third post in 3 days.
0
Question by:John Bolter

LVL 21

Expert Comment

It is working correct, you keep recreating the List.  You need to add another element like:
points = new List<PointF> { new PointF(1f, 2f) };
0

LVL 21

Expert Comment

and the 3rd time it will error since you have no entries so a dived by zero
0

LVL 74

Expert Comment

It's not a divide by zero, it's an InvalidOperationException, and you receive it because the Average method does not work across an empty sequence (e.g. List). You must have at least one element in the sequence before calling Average.

One approach:

private Single getAverageX(List<PointF> points)
{
if (points.Count == 0)
{
return 0;
}

Single average = (from point in points
select point.X
).Average();

return average;
}

0

Author Comment

Thanks everyone, so the FirstOrDefault method cannot somehow be used to provide a value of 0 when there are no items in the list?
0

LVL 21

Expert Comment

as kaufmed showed, use that to provide a return when no ittems exist.
0

LVL 74

Accepted Solution

IMO, FirstOrDefault doesn't make sense here. With that method you are saying, "Give me the first element in the list, unless the list is empty, then give the default value for the type the list contains." I think you would be better served by DefaultIfEmpty:

e.g.

private Single getAverageX(List<PointF> points)
{
Single average = (from point in points
select point.X
).DefaultIfEmpty().Average();

return average;
}

0

Author Comment

Thanks

The following code does not compile, but it does use FirstOrDefault how I think it could be used.

private Single getAverageX(List<PointF> points)
{
Single average = (from point in points
select point.X
).FirstOrDefault(0f).Average();

return average;
}

So how is FirstOrDefault used here rather than having the extra if statement?

I hope this makes sense.

Thank you

John B
0

Author Comment

Yes, DefaultIfEmpty is what I was after. Thank you, I was close, but I had been close to sorting this for 3 hours!
0

Author Closing Comment

Thank you!!
0

LVL 21

Expert Comment

lol, ok kind of missed me answering first part of this question? :P
0

## Featured Post

In my previous article (http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_3.x/A_4362-Serialization-in-NET-1.html) we saw the basics of serialization and how types/objects can be serialized to Binary format. In this blog we wi…
Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…