tags:

views:

43

answers:

2

I have a list of Datapoints (List).

e.g

original list
(1,2)
(2,2)
(1,3)
(3,3)
(4,3)
(2,3)
(5,4)

I want a output list as

(1,2)
(2,2)
(3,3)
(4,3)
(5,4)
or

(1,3)
(3,3)
(4,3)
(2,3)
(5,4)

i.e I want to remove all the other points where X value duplicates.

One approach that I have is to loop through all the point and take the current point x value and compare it with rest of the list if it equals other points X value then remove that value.

How will I do that using LINQ or some extension method(Distinct)

+2  A: 

One approach with LINQ would be to group points by their X-coordinates, and then pick some arbitrary item from each group to produce the output.

var filtered = myList.GroupBy(point => point.XValue) // point's bucket depends on its X
                     .Select(group => group.First()) //pick first item from each bucket
                     .ToList();

EDIT: A simple way of doing it without LINQ:

var pointsByXCoord = new Dictionary<double, DataPoint>();

foreach(var point in myList)
   pointsByXCoord[point.XValue] = point;

var filtered = pointsByXCoord.Values;
Ani
Although this has worked for me, will it be a costly operation than a nested foreach??
Mohit
@Mohit: In principle, this approach should be much faster than your original suggestion. The only way to find out is to measure, though.
Ani
+1  A: 

var enumerable = myList.Distinct() will return an IEnumerable<Datapoint> as long as the Datapoint has implemented the IEquatable<> interface.

Here is a nice article on the requirements for the custom type in order to be able to use Distinct() extension from LINQ:

http://blogs.msdn.com/b/csharpfaq/archive/2009/03/25/how-to-use-linq-methods-to-compare-objects-of-custom-types.aspx

If you need a list instead of an IEnumerable a ToList() extension is also provided.

jdehaan