不同的值列表

时间:2014-01-23 09:46:41

标签: c# list unique

我正在尝试从List位置获取Locations。所有的值必须是彼此独一无二的。

我问自己,我能做得最好。

位置包含纬度和经度。

List<Location> locations;

Location a,b,c,d;
a = locations[....]
b = locations[....]
c = locations[....]
d = locations[....]

那么我应该如何给出a,b,c和d所有唯一值,以便没有位置相等?

3 个答案:

答案 0 :(得分:1)

您应该覆盖班级中的EqualsGetHashCode,例如:

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);
    }
}

现在您已经可以使用Enumerable.Distinct删除重复项:

var uniqeLocations = locations.Distinct().ToList();

答案 1 :(得分:0)

在数组实例上使用Union方法合并不同的项目(请记住包含using System.Linq以访问Linq特定的扩展方法):

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);
        }
    }
}

答案 2 :(得分:0)

如果您不想或不能更改Location课程的实施,并且您需要获得不同的位置,您可以按纬度和经度对它们进行分组,然后从每个组中选择第一个位置(全部组中的位置将具有相同的纬度和经度):

var distinctLocations = from l in locations
                        group l by new { l.Latitude, l.Longitude } into g
                        select g.First();

但是,当然,如果这不是您需要比较位置的单一地方,那么您应该使用@Tim Schmelter解决方案。

更新:获取独特的随机位置:

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();