0

配列の重複した値を保存したい、または同じものを一意の名前を削除したい。

たとえば、次の内容の配列がある場合:

{a, b, c, c, c}

これを他の配列に保存したい:

{c, c, c}

For ループを使用して操作を実行する方法は知っていますが、LINQ 拡張機能を使用してコードを改善したいと考えています (可能な場合)。

4

2 に答える 2

2

これはあなたが望むことですが、元のコレクションの要素を並べ替えます。

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

2 つの違いを得るには、Except を使用して次のようにします。

var exceptResult = yourArray.Except(query);
于 2013-09-07T22:00:03.317 に答える
1

(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();
    }
}
于 2013-09-08T08:35:19.670 に答える