【问题标题】:Get index of an object in a Generic list获取通用列表中对象的索引
【发布时间】:2021-06-13 06:32:37
【问题描述】:

我有一个自定义对象列表,其中包含两个属性作为标识符(IDa 和 IDb)。

每次我删除一个对象时,我都需要知道它的索引。如何在不循环所有列表的情况下获取对象的索引?

List<CustomObject> list = new List<CustomObject>();
list.RemoveAll((MiniMapRecord p) => p.IDa == IDa.SystemID & p.IDb == pInputRecordMap.IDb);

【问题讨论】:

  • 什么样的列表?像这样的问题通常需要 2 或 3 行代码。省去了很多猜测。
  • 您的列表是否包含 MiniMapRecord 对象,或CustomObject 类的混合?

标签: c# list generics


【解决方案1】:

你想要的方法是FindIndex(Predicate)

int index = list.FindIndex(MiniMapRecord p => p.IDa == IDa.SystemID & p.IDb == pInputRecordMap.IDb);

【讨论】:

  • 它的复杂度是多少?
  • 如果你只有对象的属性,这是要走的路。
  • 值得指出的是,FindIndex 是在内部使用 for 循环实现的。
【解决方案2】:

正如其他人所说,没有办法避免循环遍历项目以找到一个,除非您:

记住索引。创建列表时,将相关索引保存到成员变量中。这可能不适合您的问题。

或者:

保持列表排序并对项目进行二分搜索。这也可能不起作用,因为您有两个标识符。

IndexOf() 是一个简单的解决方案,但它会花费 O(N)(线性)。

【讨论】:

  • IndexOf() 如何比较两个不同的对象?
  • IndexOf() 使用默认的 EqualityComparer,因此如果您为您的项目重载相等性,您可以控制它。否则,您可以使用First()Single()(来自LINQ)并传入一个谓词来测试/比较对象。 var match = items.Single(item =&gt; item.Id == myId);
  • 感谢 Josh G,但是如果我没有为我的对象重载相等会发生什么?
  • 然后它将使用默认的相等比较器。对于没有相等覆盖的引用类型,这是一个实例比较(两个对象引用同一个实例)。对于原语,默认相等将是值比较而不是实例比较。 (var x = 4; var y = 4; x == y // is true)
  • 带默认实例比较:var x = new IntWrapper(4); var y = new IntWrapper(4); x != y // true
【解决方案3】:

您可以使用IndexOf() 方法获取List&lt;&gt; 的给定元素的索引。

但是,请注意,由于链表不意味着随机访问,因此除了从头开始并一次检查一个元素之外,实际上没有任何其他方法可以找到特定元素(以及它的索引)。

【讨论】:

  • 没有循环所有列表的方法吗?我没有对象,只有它的属性。这是一个获取数千条记录的过程,每条记录都在列表中找到并删除它。
  • 在这种情况下,我相信 MattDavey 已经回答了您的问题。
【解决方案4】:

使用列表的.IndexOf()方法查找索引,然后使用.RemoveAt()删除。

【讨论】:

  • 当然,如果你有对象要做IndexOf,你可以直接Remove(obj)。
  • 不完全。这是一个具有相同属性的新实例。如果我没记错的话,IndexOf() 是参考。
  • OP 没有说明如何通过这两个属性定位对象。我假设该对象是已知的。
  • 拒绝投票在这里似乎有点极端。从问题中并不清楚只有属性是已知的。
猜你喜欢
  • 2011-07-05
  • 1970-01-01
  • 1970-01-01
  • 2012-11-25
  • 2014-02-11
  • 1970-01-01
  • 2020-01-07
  • 1970-01-01
  • 2018-08-16
相关资源
最近更新 更多