我有一个列表<> C# 中的对象的数量,我需要一种方法来返回列表中被视为重复的那些对象。 我不需要不同的结果集,我需要一个将从我的存储库中删除的项目的列表。
就本示例而言,假设我有一个“汽车”类型列表,我需要知道其中哪些汽车与列表中的其他汽车颜色相同。 以下是列表中的汽车及其颜色属性:
Car1.Color = Red;
Car2.Color = Blue;
Car3.Color = Green;
Car4.Color = Red;
Car5.Color = Red;
对于此示例,我需要结果(IEnumerable<>、List<> 或其他)来包含 Car4 和 Car5,因为我想从我的存储库或数据库中删除它们,所以我的存储库中每种颜色只有一辆车。 任何帮助,将不胜感激。
I have a List<> of objects in C# and I need a way to return those objects that are considered duplicates within the list. I do not need the Distinct resultset, I need a list of those items that I will be deleting from my repository.
For the sake of this example, lets say I have a list of "Car" types and I need to know which of these cars are the same color as another in the list. Here are the cars in the list and their color property:
Car1.Color = Red;
Car2.Color = Blue;
Car3.Color = Green;
Car4.Color = Red;
Car5.Color = Red;
For this example I need the result (IEnumerable<>, List<>, or whatever) to contain Car4 and Car5 because I want to delete these from my repository or db so that I only have one car per color in my repository. Any help would be appreciated.
发布评论
评论(8)
我昨天无意中编写了这个代码,当时我试图写一个“通过投影来区分”。 我包括了一个! 当我不应该这样做时,但这一次它是正确的:
然后你可以用以下方式调用它:
I inadvertently coded this yesterday, when I was trying to write a "distinct by a projection". I included a ! when I shouldn't have, but this time it's just right:
You'd then call it with:
这将按颜色对汽车进行分组,然后跳过每组的第一个结果,返回每组中的剩余结果,并将其扁平化为单个序列。
如果您对要保留哪一辆有特殊要求,例如,如果汽车具有
Id
属性,并且您希望保留具有最低Id
的汽车,那么您可以在那里添加一些排序,例如This groups the cars by color and then skips the first result from each group, returning the remainder from each group flattened into a single sequence.
If you have particular requirements about which one you want to keep, e.g. if the car has an
Id
property and you want to keep the car with the lowestId
, then you could add some ordering in there, e.g.这是一个稍微不同的 Linq 解决方案,我认为它使您想要做的事情更加明显:
它只是按颜色对汽车进行分组,丢弃所有具有多个元素的组,然后将其余的放入返回的 IEnumerable 中。
Here's a slightly different Linq solution that I think makes it more obvious what you're trying to do:
It's just grouping cars by color, tossing out all the groups that have more than one element, and then putting the rest into the returned IEnumerable.
它基本上意味着“返回列表中具有相同颜色和较小索引的任何汽车的汽车”。
但不确定性能。 我怀疑使用 O(1) 查找重复项的方法(如字典/哈希集方法)对于大型集合可能会更快。
It basically means "return cars where there's any car in the list with the same color and a smaller index".
Not sure of the performance, though. I suspect an approach with a O(1) lookup for duplicates (like the dictionary/hashset method) can be faster for large sets.
创建一个新的
Dictionary foundColors
和一个List carsToDelete
然后,您可以像这样迭代原始汽车列表:
然后您可以删除foundColors 中的每辆汽车。
通过将“删除记录”逻辑放在 if 语句中而不是创建新列表,您可以获得较小的性能提升,但您提出问题的方式表明您需要将它们收集在列表中。
Create a new
Dictionary<Color, Car> foundColors
and aList<Car> carsToDelete
Then you iterate through your original list of cars like so:
Then you can delete every car that's in foundColors.
You could get a minor performance boost by putting your "delete record" logic in the
if
statement instead of creating a new list, but the way you worded the question suggested that you needed to collect them in a List.如果没有实际编码,那么像这样的算法怎么样:
List
创建一个Dictionary
Dictionary< T, int>
删除int
为 >1 的条目Dictionary
中剩余的任何内容都有重复项。 当然,实际删除的第二部分是可选的。 您只需遍历Dictionary
并查找 >1 即可采取操作。编辑:好的,我提高了瑞安的,因为他实际上给了你代码。 ;)
Without actually coding it, how about an algorithm something like this:
List<T>
creating aDictionary<T, int>
Dictionary<T, int>
deleting entries where theint
is >1Anything left in the
Dictionary
has duplicates. The second part where you actually delete is optional, of course. You can just iterate through theDictionary
and look for the >1's to take action.EDIT: OK, I bumped up Ryan's since he actually gave you code. ;)
我的回答的灵感来自于以下受访者(按此顺序):Joe Coehoorn、Greg Beech 和 Jon Skeet。
我决定提供一个完整的示例,假设(为了实际效率)您有一个静态的汽车颜色列表。 我相信下面的代码以一种优雅但不一定超高效的方式说明了该问题的完整解决方案。
我稍后会回到这里,将这个解决方案与其所有三个灵感进行比较,只是为了对比风格。 还蛮有趣的。
My answer takes inspiration (in this order) from the followers respondents: Joe Coehoorn, Greg Beech and Jon Skeet.
I decided to provide a full example, with the assumption being (for real word efficiency) that you have a static list of car colors. I believe the following code illustrates a complete solution to the problem in an elegant, although not necessarily hyper-efficient, manner.
I'm going to come back through here later and compare this solution to all three of its inspirations, just to contrast the styles. It's rather interesting.
公共静态 IQueryable 重复项(此 IEnumerable 源)其中 TSource : IComparable
{
}
public static IQueryable Duplicates(this IEnumerable source) where TSource : IComparable
{
}