我有一个对象列表。这些对象包含其他属性中的lat和lon坐标。我想只提取满足
的thoose coordonates(Math.Abs(elem1.lat - elem2.lat) > Delta && Math.Abs(elem1.lon - elem2.lon) > Delta)
基本上我想只提取没有坐标的对象。
使用C#LINQ有一种优雅的方法吗?
编辑1:
所以elem1和elem2是列表中的任何2个元素。查询产生的元素在其中任何两个之间具有更多的增量
编辑2:
这是我目前的代码。它按我的意愿运作:
for (int i = 0; i < companyHistory.Count; i++)
{
var isOk = true;
var count = zoomApprovedHistory.Count;
for (var j = 0; j < count; j++)
{
if (Math.Abs(companyHistory[i].X - zoomApprovedHistory[j].X) < delta && Math.Abs(companyHistory[i].Y - zoomApprovedHistory[j].Y) < delta)
{
isOk = false;
break;
}
}
// if no other point is close add it to approved array for this zoom
if (isOk)
{
zoomApprovedHistory.Add(companyHistory[i]);
}
}
我该如何优化它?它具有O(n ^ 2)复杂度。寻找最快的选择
答案 0 :(得分:0)
你的问题没有得到很好的解释。如果您的elem1
或elem2
是您想要比较的单个项目,那么这非常简单。只需执行LINQ Where
即可找到符合条件的项目。
Coordinates it = new Coordinates { lat = 5, lon = 5 };
var picked = list.Where(x => Math.Abs(x.lat - it.lat) < Delta && Math.Abs(x.lon - it.lon) < Delta);
另一方面,如果你的两个元素是列表中的任何两个元素,那么你会遇到一个需要澄清问题的问题。正如我在评论中提到的那样,如果您有elem1
,elem2
和elem3
,并且前两个符合条件,但elem2
和{{elem3
1}}匹配标准,那么这两个元素(2和3)'点击'?假设它们是,下面的解决方案将起作用。我写了一个简单的Comparer来帮助简化事情。
public class CoordinateComparer : IEqualityComparer<Coordinates>
{
public bool Equals(Coordinates x, Coordinates y)
{
return (x.lat == y.lat && x.lon == y.lon);
}
public int GetHashCode(Coordinates obj)
{
unchecked
{
int hash = 17;
if (obj != null)
{
hash = hash * 23 + obj.lat.GetHashCode();
hash = hash * 23 + obj.lon.GetHashCode();
}
return hash;
}
}
}
public class Coordinates
{
public int lat { get; set; }
public int lon { get; set; }
}
class MainClass
{
public static void Main(string[] args)
{
List<Coordinates> list = new List<Coordinates>();
list.Add(new Coordinates { lat = 5, lon = 4 });
list.Add(new Coordinates { lat = 4, lon = 5 });
list.Add(new Coordinates { lat = 7, lon = 4 });
list.Add(new Coordinates { lat = 6, lon = 3 });
list.Add(new Coordinates { lat = 8, lon = 2 });
double Delta = 1.1;
List<Coordinates> results = new List<Coordinates>();
foreach(Coordinates item in list)
{
// Find items that match the condition
var matches = list.Where(x => Math.Abs(x.lat - item.lat) < Delta && Math.Abs(x.lon - item.lon) < Delta);
// The 'item' will always match the condition with itself, which is undesirable, so remove it
matches = matches.Except(new List<Coordinates> { item }, new CoordinateComparer());
// Add the items that are not already in it to the results list
results.AddRange(matches.Where(x => !results.Contains(x, new CoordinateComparer())));
}
foreach (Coordinates item in results)
Console.WriteLine("Lat : {0}, Lon : {1}", item.lat, item.lon);
Console.ReadLine();
}
}
请记住,如果你的纬度和经度坐标是double
或float
,它们可能是你的,你可能会在比较时遇到问题。但这是一个完全不同的问题。