C# 在C语言中从列表中选择唯一的元素

C# 在C语言中从列表中选择唯一的元素,c#,list,C#,List,如何从列表{0,1,2,2,2,3,4,4,5}中选择唯一的元素,从而得到{0,1,3,5},从而有效地删除重复元素{2,4}的所有实例 请确保您使用的是Linq和.NET framework 3.5。如果因为必须支持无法升级的旧代码而无法使用Linq,请声明一个字典,其中第一个int是数字,第二个int是出现的次数。循环浏览你的列表,加载你的字典。完成后,在字典中循环,只选择出现次数为1的元素。C 2.0解决方案: var numbers = new[] { 0, 1, 2, 2, 2, 3,

如何从列表{0,1,2,2,2,3,4,4,5}中选择唯一的元素,从而得到{0,1,3,5},从而有效地删除重复元素{2,4}的所有实例


请确保您使用的是Linq和.NET framework 3.5。

如果因为必须支持无法升级的旧代码而无法使用Linq,请声明一个字典,其中第一个int是数字,第二个int是出现的次数。循环浏览你的列表,加载你的字典。完成后,在字典中循环,只选择出现次数为1的元素。

C 2.0解决方案:

var numbers = new[] { 0, 1, 2, 2, 2, 3, 4, 4, 5 };

var uniqueNumbers =
    from n in numbers
    group n by n into nGroup
    where nGroup.Count() == 1
    select nGroup.Key;

// { 0, 1, 3, 5 }
static IEnumerable<T> GetUniques<T>(IEnumerable<T> things)
{
    Dictionary<T, int> counts = new Dictionary<T, int>();

    foreach (T item in things)
    {
        int count;
        if (counts.TryGetValue(item, out count))
            counts[item] = ++count;
        else
            counts.Add(item, 1);
    }

    foreach (KeyValuePair<T, int> kvp in counts)
    {
        if (kvp.Value == 1)
            yield return kvp.Key;
    }
}
public IEnumerable<T> Distinct<T>(IEnumerable<T> source)
{
     List<T> uniques = new List<T>();
     foreach (T item in source)
     {
         if (!uniques.Contains(item)) uniques.Add(item);
     }
     return uniques;
}

我相信马特的意思是:

 static IEnumerable<T> GetUniques<T>(IEnumerable<T> things)
 {
     Dictionary<T, bool> uniques = new Dictionary<T, bool>();
     foreach (T item in things)
     {
         if (!(uniques.ContainsKey(item)))
         {
             uniques.Add(item, true);
         }
     }
     return uniques.Keys;
 }
和lambda

var all = new[] {0,1,1,2,3,4,4,4,5,6,7,8,8}.ToList();
var unique = all.GroupBy(i => i).Where(i => i.Count() == 1).Select(i=>i.Key);

在.Net 2.0中,我非常肯定这个解决方案:

static IEnumerable<T> GetUniques<T>(IEnumerable<T> things)
{
    Dictionary<T, int> counts = new Dictionary<T, int>();

    foreach (T item in things)
    {
        int count;
        if (counts.TryGetValue(item, out count))
            counts[item] = ++count;
        else
            counts.Add(item, 1);
    }

    foreach (KeyValuePair<T, int> kvp in counts)
    {
        if (kvp.Value == 1)
            yield return kvp.Key;
    }
}
public IEnumerable<T> Distinct<T>(IEnumerable<T> source)
{
     List<T> uniques = new List<T>();
     foreach (T item in source)
     {
         if (!uniques.Contains(item)) uniques.Add(item);
     }
     return uniques;
}

如果您的列表中有复杂类型的对象,并且希望获取属性的唯一值,则以下是另一种方法:

var uniqueValues= myItems.Select(k => k.MyProperty)
                  .GroupBy(g => g)
                  .Where(c => c.Count() == 1)
                  .Select(k => k.Key)
                  .ToList();
或获取不同的值:

var distinctValues = myItems.Select(p => p.MyProperty)
                            .Distinct()
                            .ToList();
如果属性也是复杂类型,则可以为Distinct创建自定义比较器,例如DistinctOrderComparer,其中OrderComparer可能类似于:

public class OrderComparer : IEqualityComparer<Order>
{
    public bool Equals(Order o1, Order o2)
    {
        return o1.OrderID == o2.OrderID;
    }

    public int GetHashCode(Order obj)
    {
        return obj.OrderID.GetHashCode();
    }
}

有很多方法可以剥猫的皮,但是HashSet似乎适合这里的任务

var numbers = new[] { 0, 1, 2, 2, 2, 3, 4, 4, 5 };

HashSet<int> r = new HashSet<int>(numbers);

foreach( int i in r ) {
    Console.Write( "{0} ", i );
}
输出:



0123445

返回{0,1,2,3,4,5}包括重复元素。哦,我的错误。我没有注意到你想要删除那些重复的条目。至少在C之外,我不能说对于C本身,如果它包含重复的条目,那么起点实际上不是一个集合。它可能是一个多集合,或者一个列表,或者……这将抛出一个KeyNotFoundException。这是可行的,但您需要更改计数[item]++;输入if counts.ContainsKeyitem计数[项目]+;除此之外,还有1项;这是CVertex发布的.NET2.0版本。它还返回重复的元素。不,我更喜欢保留这些元素,因为法国人说英国人偶尔会射杀一名海军上将“pour encourager l'autres.OMG”。那太好了。HashSet r=新的HashSetnumbers如何@蒂梅克:OP想要删除重复的数字,只留下那些在原始序列中唯一的数字。我迷路了。您提供的代码没有修改名为“数字”的原始序列。@Tymek:OP要求选择唯一的数字,这意味着通过检查现有序列来创建一个新序列。@Tymek:非常接近。它将是{0,1,3,5},因为只有2和4重复。但是我想你明白了。谢谢你,但是我想从原始列表中删除所有重复元素的实例,例如,{0,1,1,2,2,3}->{0,3},因为它是类列表的对象,你想修改它?我更喜欢这个。更短更容易阅读?使用lamba表达式。@EwaldStieger,他不想为每个值留下一个实例,他想删除所有出现超过一次的值实例。那么,Distinct如何实现这一点呢?我对8票赞成感到惊讶,因为你的答案没有正确地解决问题。@MassimilianoKraus是的,你是对的。我在最初的答案中遗漏了这一点,现在已经对其进行了更新,但这种方法增加了所有的现值。他不想要这个。他希望完全删除重复的值。请注意,为了对对象使用此解决方案,如果要获取具有唯一特定键/字段的对象列表,则需要将最终选择替换为SelectMany:.SelectManyi=>i,这将使IEnumerable变平为IEnumerable。使用对象或其他方式执行此操作的另一种方法是将Where和Select替换为从中收集的.Selectx=>x.FirstOrDefault。