Reputation: 107
I am trying to get Locations out of a List locations. All of the values has to be unique from eachother in sequence.
I ask myself what I can do best.
Location contains a Latitude and a longitude.
List<Location> locations;
Location a,b,c,d;
a = locations[....]
b = locations[....]
c = locations[....]
d = locations[....]
So how should I give a,b,c and d all unique values, so that there's no Location equal to each other?
Upvotes: 0
Views: 140
Reputation: 236188
If you don't want or can't change implementation of your Location
class, and you need to get distinct locations, you can group them by latitude and longitude and then select first location from each group (all locations in group will have same latitude and longitude):
var distinctLocations = from l in locations
group l by new { l.Latitude, l.Longitude } into g
select g.First();
But of course, if that is not single place where you need to compare locations, you should go with @Tim Schmelter solution.
UPDATE: Getting unique random locations:
Random rnd = new Random();
List<Location> uniqueRandomLocations =
locations.GroupBy(l => new { l.Latitude, l.Longitude })
.Select(g => g.First())
.OrderBy(l => rnd.Next())
.Take(N)
.ToList();
Upvotes: 0
Reputation: 3455
Use the Union
method on array instances to merge distinct items (remember to include using System.Linq
to get access to Linq specific extension methods):
using System;
using System.Linq;
namespace DistinctValues
{
public struct Location
{
public Location(double longitude, double latitude) : this()
{
this.Longitude = longitude;
this.Latitude = latitude;
}
public double Longitude { get; set; }
public double Latitude { get; set; }
public override string ToString()
{
return string.Format("Longitude: {0}, Latitude={1}", this.Longitude, this.Latitude);
}
}
class Program
{
static void Main(string[] args)
{
var a = new Location[]
{
new Location(123.456, 456.789),
new Location(123.456, 456.789),
new Location(234.567, 890.123),
};
var b = new Location[]
{
new Location(123.456, 456.789),
new Location(890.123, 456.789),
};
// Join array a and b. Uses union to pick distinct items from joined arrays
var result = a.Union(b);
// Dump result to console
foreach(var item in result)
Console.WriteLine(item);
}
}
}
Upvotes: 0
Reputation: 460028
You should override Equals
and GetHashCode
in your class, for example:
public class Location
{
public int Latitude { get; set; }
public int Longitude { get; set; }
public override bool Equals(object obj)
{
if(obj == null)return false;
if(object.ReferenceEquals(this, obj)) return true;
Location l2 = obj as Location;
if(l2 == null) return false;
return Latitude == l2.Latitude && Longitude == l2.Longitude;
}
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
hash = hash * 23 + Latitude.GetHashCode();
hash = hash * 23 + Longitude.GetHashCode();
return hash;
}
}
public override string ToString()
{
return string.Format("{0},{1}", Latitude, Longitude);
}
}
Now you can already use Enumerable.Distinct
to remove duplicates:
var uniqeLocations = locations.Distinct().ToList();
Upvotes: 1