根据结构列表上的条件查找 FirstOrDefault
Posted
技术标签:
【中文标题】根据结构列表上的条件查找 FirstOrDefault【英文标题】:Find FirstOrDefault based on conditions on a struct list 【发布时间】:2021-11-16 02:46:41 【问题描述】:我有 2 个列表,即具有 4 个 Vector3 值 C1、C2、C3、C4 的 clist 和名为 plist 的第二个列表,具有 4 个 vector3 值 P1、P2、P3、P4。我需要找到从 clist 中的向量到 plist 中的向量的最小距离。例如,需要求出 C1 到 P1、P2、P3 和 P4 的距离。 C2 到 P1、P2、P3 和 P4。 C3 到 P1、P2、P3、P4。 C4 到 P1、P2、P3、P4。
为此,我添加了一个结构来存储这些数据,如下所示:
public struct CPDistance
public GameObject p;
public GameObject c;
public float distance;
并使用代码创建了此结构的新列表:
public List<CPDistance> tempstruct = new List<CPDistance>();
我使用代码找到了这些向量之间的距离:
foreach (var ca in clist)
foreach (var pa in plist)
CPDistance cpd = new CPDistance();
cpd.p = pa;
cpd.c= ca;
cpd.distance = Vector3.Distance(ca.transform.position, pa.transform.position);
tempstruct.Add(cpd);
IEnumerable<CPDistance> query = tempstruct.OrderBy(x => x.distance);
foreach (var item in query)
Debug.Log(item.c.name + " " + item.p.name + " " + item.distance);
在运行上述代码时,我得到如下输出:
C4 P1 0.5526165
C2 P3 1.242753
C1 P4 1.519395
C3 P1 1.891354
C2 P4 2.189372
C1 P3 2.390067
C4 P2 4.378077
C3 P2 5.170161
C3 P3 7.519557
C1 P2 7.856441
C3 P4 7.938454
C2 P1 8.108953
C1 P1 8.33768
C2 P2 8.851195
C4 P3 9.264006
C4 P4 9.530743
从图中可以看出,C1靠近P4,C2靠近P3,C4靠近P1,剩下的C3靠近P2。我需要得到这样的输出:
C1 P4 1.519395
C2 P3 1.242753
C4 P1 0.5526165
C3 P2 5.170161
我听说有一个名为 Firstordefault 的代码,其中可以将条件赋予变量查询以获得上述所需的输出。我给出了这样的代码:
foreach (var i in clist)
query.FirstOrDefault(x => x.p == i);
但它没有提供所需的输出。有人可以帮我找出使用 FirstorDefault 代码有什么问题吗?
【问题讨论】:
Hmm...FirstOrDefault
只返回列表中的第一个元素,如果不存在元素,则返回默认值null
:docs.microsoft.com/en-us/dotnet/api/…
A) 你对返回值做了什么吗? B) 你如何比较来自clist
和x.p
的对象,这显然可能只包含来自plist
的对象?
【参考方案1】:
如果您只是想找到离每个项目最近的点,您可以使用 LINQ 轻松做到这一点:
var closestToEachP = data.GroupBy(e => e.p)
.Select(g => g.OrderBy(e => e.distance).First())
.ToList();
但是,当我们发现靠近它的另一个项目时,您似乎需要将每个点作为一个选项删除。为此,您需要跟踪找到的项目。看起来像这样:
var seenPValues = new HashSet<string>();
var seenCValues = new HashSet<string>();
var closestPairs = new List<CPDistance>();
foreach (var element in data.OrderBy(e => e.distance))
if(!seenPValues.Contains(element.p) && !seenCValues.Contains(element.c))
seenPValues.Add(element.p);
seenCValues.Add(element.c);
closestPairs.Add(element);
【讨论】:
以上是关于根据结构列表上的条件查找 FirstOrDefault的主要内容,如果未能解决你的问题,请参考以下文章