从 C# 列表中选择唯一元素

发布于 2024-07-09 03:44:02 字数 135 浏览 7 评论 0原文

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

How do I select the unique elements from the list {0, 1, 2, 2, 2, 3, 4, 4, 5} so that I get {0, 1, 3, 5}, effectively removing all instances of the repeated elements {2, 4}?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

り繁华旳梦境 2024-07-16 03:44:02
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 }
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 }
不语却知心 2024-07-16 03:44:02
var nums = new int{ 0...4,4,5};
var distinct = nums.Distinct();

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

var nums = new int{ 0...4,4,5};
var distinct = nums.Distinct();

make sure you're using Linq and .NET framework 3.5.

晨光如昨 2024-07-16 03:44:02

与拉姆达..

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);

With 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);
橙味迷妹 2024-07-16 03:44:02

C#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;
    }
}

C# 2.0 solution:

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;
    }
}
并安 2024-07-16 03:44:02

如果您的列表中有复杂类型对象并且想要获取属性的唯一值,那么这里是另一种有效的方法:

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( 创建一个自定义比较器),例如 Distinct(OrderComparer),其中 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();
    }
}

Here is another way that works if you have complex type objects in your List and want to get the unique values of a property:

var uniqueValues= myItems.Select(k => k.MyProperty)
                  .GroupBy(g => g)
                  .Where(c => c.Count() == 1)
                  .Select(k => k.Key)
                  .ToList();

Or to get distinct values:

var distinctValues = myItems.Select(p => p.MyProperty)
                            .Distinct()
                            .ToList();

If your property is also a complex type you can create a custom comparer for the Distinct(), such as Distinct(OrderComparer), where OrderComparer could look like:

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();
    }
}
云柯 2024-07-16 03:44:02

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

If Linq isn't available to you because you have to support legacy code that can't be upgraded, then declare a Dictionary, where the first int is the number and the second int is the number of occurences. Loop through your List, loading up your Dictionary. When you're done, loop through your Dictionary selecting only those elements where the number of occurences is 1.

眼角的笑意。 2024-07-16 03:44:02

我相信马特的意思是:

 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;
 }

I believe Matt meant to say:

 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;
 }
做个ˇ局外人 2024-07-16 03:44:02

剥猫皮的方法有很多种,但 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 );
}

输出:

0 1 2 3 4 5

There are many ways to skin a cat, but HashSet seems made for the task here.

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 );
}

The output:

0 1 2 3 4 5

小草泠泠 2024-07-16 03:44:02

这是一个没有 LINQ 的解决方案:

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

// This assumes the numbers are sorted
var noRepeats = new List<int>();
int temp = numbers[0]; // Or .First() if using IEnumerable
var count = 1;
for(int i = 1; i < numbers.Length; i++) // Or foreach (var n in numbers.Skip(1)) if using IEnumerable
{
    if (numbers[i] == temp) count++;
    else
    {
        if(count == 1) noRepeats.Add(temp);
        temp = numbers[i];
        count = 1;
    }
}
if(count == 1) noRepeats.Add(temp);

Console.WriteLine($"[{string.Join(separator: ",", values: numbers)}] -> [{string.Join(separator: ",", values: noRepeats)}]");

打印:

[0,1,2,2,2,3,4,4,5] -> [0,1,3,5]

Here's a solution with no LINQ:

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

// This assumes the numbers are sorted
var noRepeats = new List<int>();
int temp = numbers[0]; // Or .First() if using IEnumerable
var count = 1;
for(int i = 1; i < numbers.Length; i++) // Or foreach (var n in numbers.Skip(1)) if using IEnumerable
{
    if (numbers[i] == temp) count++;
    else
    {
        if(count == 1) noRepeats.Add(temp);
        temp = numbers[i];
        count = 1;
    }
}
if(count == 1) noRepeats.Add(temp);

Console.WriteLine(
quot;[{string.Join(separator: ",", values: numbers)}] -> [{string.Join(separator: ",", values: noRepeats)}]");

This prints:

[0,1,2,2,2,3,4,4,5] -> [0,1,3,5]
甜味超标? 2024-07-16 03:44:02

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

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;
}

In .Net 2.0 I`m pretty sure about this solution:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文