根据结构列表上的条件查找 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) 你如何比较来自clistx.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的主要内容,如果未能解决你的问题,请参考以下文章

js中树结构根据条件查找节点返回节点路径的一些思路

Python根据条件在数组中查找索引

根据列表值在 Power Query 中创建条件列

[数据结构] 散列表(哈希表)

数据结构查找---散列表(哈希表)查找

数据结构—— 散列查找:散列表