【问题标题】:Delete unique values of an Array using LINQ?使用 LINQ 删除数组的唯一值?
【发布时间】:2013-09-07 21:50:07
【问题描述】:

我想存储一个数组的重复值,或者我想删除唯一名称。

例如,如果我有一个包含此内容的数组:

{a, b, c, c, c}

我想将它存储在其他数组中:

{c, c, c}

我知道如何使用 For 循环执行操作,但我想使用 LINQ 扩展来改进代码(如果可能的话)。

【问题讨论】:

  • 所以,原始数组只保留{a, b},甚至没有一个c?另外,输入是否排序?性能要求是什么? (因为如果性能是任何因素,我建议循环+Array.Resize
  • @sehe,真的,无论第一个数组是否保留 C,而新数组是否包含重复值 1 次,是的,数组已排序,就像我说过的那样,我不喜欢使用他有用的 LINQ 扩展来改进它,感谢您的评论。

标签: .net arrays vb.net linq duplicates


【解决方案1】:

这可以满足您的需求,但会重新排列原始集合中的元素。

var query = yourArray.GroupBy(x=>x)
     .Where(x=>x.Count() > 1)
     .SelectMany(x=>x)
     .ToArray();

要获得两者之间的区别,您可以使用 except,做:

var exceptResult = yourArray.Except(query);

【讨论】:

  • 是的,这就是我对“表现不佳”的想法。然而,几只无助的表演小猫却在角落里默默地哭泣。确实,对输入进行排序后,一个简单的一次性算法会更加高效,并且可以说更加清晰......
  • @sehe 我同意这个问题实际上并不需要 LINQ。但是由于他要求提供 LINQ 解决方案,我提供了它:) 在 cmets 中有性能评论就足够了,记住每个人这不是理想的方法
  • 我尝试过类似 array1.except(array1.distinct) 但不起作用,我评论说'因为如果你可以使用 linq 有更好的性能想法,你们会考虑在 Array使用@Save 代码可以有大约 100 个条目(没有更多)可能会对性能造成太大的负面影响?
【解决方案2】:

(在 C# 中)这是一个比执行 GroupBy/Where/SelectMany(和枚举的 Count())快得多的实现。但我必须同意这是更多的代码;-)

var array = new[] { 1, 2, 3, 3, 3 };
var valueCounter = new ValueCounter<int>(array);
var query = valueCounter.Where(p => p.Value > 1)
    .SelectMany(p => Enumerable.Repeat(p.Key, p.Value)).ToArray();

使用这个 ValueCounter 类:

public class ValueCounter<T> : IEnumerable<KeyValuePair<T, int>>
{
    private readonly IEqualityComparer<T> _comparer;
    private readonly Dictionary<T, int> _valueCounter;
    private int _nullCount = 0;

    public ValueCounter(IEnumerable<T> values, IEqualityComparer<T> comparer)
    {
        _comparer = comparer ?? EqualityComparer<T>.Default;
        _valueCounter = new Dictionary<T, int>(_comparer);
        if (values != null)
        {
            foreach (var value in values)
            {
                Add(value);
            }
        }
    }

    public ValueCounter(IEqualityComparer<T> comparer)
        : this(null, comparer)
    {
    }

    public ValueCounter(IEnumerable<T> values)
        : this(values, null)
    {
    }

    public ValueCounter()
        : this(null, null)
    {
    }

    public void Add(T value)
    {
        if (value == null)
        {
            _nullCount++;
        }
        else
        {
            int count;
            if (_valueCounter.TryGetValue(value, out count))
            {
                _valueCounter[value] = count + 1;
            }
            else
            {
                _valueCounter.Add(value, 1);
            }
        }
    }

    /// <summary>
    /// Removes a value 
    /// </summary>
    /// <param name="value">The value that needs to be removed</param>
    /// <returns>True if a value was removed</returns>
    public bool Remove(T value)
    {
        if (value == null)
        {
            if (_nullCount > 0)
            {
                _nullCount--;
                return true;
            }
        }
        else
        {
            int count;
            if (_valueCounter.TryGetValue(value, out count))
            {
                if (count == 1)
                {
                    _valueCounter.Remove(value);
                }
                else
                {
                    _valueCounter[value] = count - 1;
                }
                return true;
            }
        }
        return false;
    }

    public int GetCount(T value)
    {
        int result;
        _valueCounter.TryGetValue(value, out result);
        return result;
    }

    public IEnumerator<KeyValuePair<T, int>> GetEnumerator()
    {
        return _valueCounter.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 2020-09-20
    • 1970-01-01
    • 2013-10-11
    • 2014-11-05
    • 2020-11-02
    • 2022-12-22
    相关资源
    最近更新 更多