如何检查列表中是否包含指定数量的同一对象
高效检测GameObject列表中的重复项
嘿,我完全懂你现在的麻烦——手动循环查找、存临时变量再删除的方法不仅繁琐,还很容易出bug(比如误删元素或者漏统计)。其实我们可以用更简洁可靠的方式来统计列表里的重复GameObject,核心思路是分组计数,根据你要检测的是「同一实例的重复引用」还是「同类型对象(名称+标签一致)」,可以用不同的实现方式:
情况1:检测同一GameObject实例的重复引用
如果你的列表里不小心多次添加了同一个GameObject实例(引用完全相同),可以直接按实例本身分组:
using System.Linq; using UnityEngine; // 假设你的GameObject列表是这个 List<GameObject> gameObjectList = new List<GameObject>(); // 分组统计每个实例的出现次数 var duplicateInstances = gameObjectList .GroupBy(go => go) // 按GameObject实例分组(每个实例的引用唯一) .Where(group => group.Count() >= 3) // 筛选出现3次及以上的组 .Select(group => group.Key); // 输出结果 if (duplicateInstances.Any()) { foreach (var duplicateGo in duplicateInstances) { int repeatCount = gameObjectList.Count(go => go == duplicateGo); Debug.Log($"找到重复实例:{duplicateGo.name}(实例ID:{duplicateGo.GetInstanceID()}),共出现{repeatCount}次"); } } else { Debug.Log("没有找到重复3次及以上的GameObject实例"); }
情况2:检测同名同标签的对象(不同实例但属于同一类)
如果你的需求是统计「名称和标签都相同的不同GameObject实例」,可以用名称+标签的组合键来分组:
using System.Linq; using UnityEngine; List<GameObject> gameObjectList = new List<GameObject>(); // 用匿名类作为分组键,同时匹配名称和标签 var duplicateTypeObjects = gameObjectList .GroupBy(go => new { go.name, go.tag }) .Where(group => group.Count() >= 3) .Select(group => group.Key); // 输出结果 if (duplicateTypeObjects.Any()) { foreach (var key in duplicateTypeObjects) { int repeatCount = gameObjectList.Count(go => go.name == key.name && go.tag == key.tag); Debug.Log($"找到重复类型对象:名称={key.name},标签={key.tag},共出现{repeatCount}次"); } } else { Debug.Log("没有找到重复3次及以上的同名同标签GameObject"); }
不用Linq的替代方案(适合新手或性能敏感场景)
如果你不想用Linq,也可以用Dictionary手动计数,逻辑更直观:
using System.Collections.Generic; using UnityEngine; List<GameObject> gameObjectList = new List<GameObject>(); // 1. 统计实例重复次数 Dictionary<GameObject, int> instanceCounter = new Dictionary<GameObject, int>(); foreach (var go in gameObjectList) { if (instanceCounter.ContainsKey(go)) { instanceCounter[go]++; } else { instanceCounter[go] = 1; } } // 检查并输出重复实例 foreach (var pair in instanceCounter) { if (pair.Value >= 3) { Debug.Log($"实例{pair.Key.name}重复了{pair.Value}次,实例ID:{pair.Key.GetInstanceID()}"); } } // 2. 统计同名同标签对象的重复次数 Dictionary<string, int> nameTagCounter = new Dictionary<string, int>(); foreach (var go in gameObjectList) { // 用"名称_标签"作为唯一键 string key = $"{go.name}_{go.tag}"; if (nameTagCounter.ContainsKey(key)) { nameTagCounter[key]++; } else { nameTagCounter[key] = 1; } } // 检查并输出重复类型对象 foreach (var pair in nameTagCounter) { if (pair.Value >= 3) { string[] keyParts = pair.Key.Split('_'); Debug.Log($"名称={keyParts[0]}、标签={keyParts[1]}的对象重复了{pair.Value}次"); } }
这些方法都不会修改你的原列表(除非你之后主动删除重复项),比你原来的方案更高效也更不容易出错,尤其是当列表元素较多的时候优势更明显。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

