编辑:我已经更新了UniqueBy
底部的实现以显着提高效率,并且只遍历源一次。
如果我对您的理解正确(问题很不清楚-如果您能提供一个示例,这将非常有帮助),这就是您想要的:
public static IEnumerable<T> OnlyUnique<T>(this IEnumerable<T> source)
{
// No error checking :)
HashSet<T> toReturn = new HashSet<T>();
HashSet<T> seen = new HashSet<T>();
foreach (T element in source)
{
if (seen.Add(element))
{
toReturn.Add(element);
}
else
{
toReturn.Remove(element);
}
}
// yield to get deferred execution
foreach (T element in toReturn)
{
yield return element;
}
}
编辑:好的,如果您只关心列表的第一个元素的唯一性,我们需要对其进行一些更改:
public static IEnumerable<TElement> UniqueBy<TElement, TKey>
(this IEnumerable<TElement> source,
Func<TElement, TKey> keySelector)
{
var results = new LinkedList<TElement>();
// If we've seen a key 0 times, it won't be in here.
// If we've seen it once, it will be in as a node.
// If we've seen it more than once, it will be in as null.
var nodeMap = new Dictionary<TKey, LinkedListNode<TElement>>();
foreach (TElement element in source)
{
TKey key = keySelector(element);
LinkedListNode<TElement> currentNode;
if (nodeMap.TryGetValue(key, out currentNode))
{
// Seen it before. Remove if non-null
if (currentNode != null)
{
results.Remove(currentNode);
nodeMap[key] = null;
}
// Otherwise no action needed
}
else
{
LinkedListNode<TElement> node = results.AddLast(element);
nodeMap[key] = node;
}
}
foreach (TElement element in results)
{
yield return element;
}
}
你可以这样称呼它:
list.UniqueBy(row => row[0])