0

リストに同じアイテムが3つあるかどうかを確認する必要があります。

オーバーライドされた.Equals()メソッドを使用して要素を比較する必要があります。私は多くの方法を試しましたが失敗しました。ブール値を返すか、アイテム自体を返すかは関係ありません。この関数は、新しいアイテムが追加されるたびに呼び出されるため、同じアイテムが3つリストされているポイントを検出する限り、この関数は問題になりません。

これはおそらく些細なことですが、Linqに関する私の知識は非常に弱いです。

4

6 に答える 6

1

To express better my concept:

static class EnumerableExtensions
{
    public static IEnumerable<T> FirstRepeatedTimes<T>(this IEnumerable<T> sequence, int threshold)
    {
        if (!sequence.Any())
            throw new ArgumentException("Sequence must contain elements", "sequence");
        if (threshold < 2)
            throw new ArgumentException("DuplicateCount must be greater than 1", "threshold");

        return FirstRepeatedTimesImpl(sequence, threshold);
    }

    static IEnumerable<T> FirstRepeatedTimesImpl<T>(this IEnumerable<T> sequence, int threshold)
    {
        var map = new Dictionary<T, int>();
        foreach(var e in sequence)
        {
            if (!map.ContainsKey(e))
                map.Add(e, 0);
            if (map[e] + 1 == threshold)
            {
                yield return e;
                yield break;
            }
            map[e] = map[e] + 1;
        }
    }
}

you would use it like this:

var list = new List<int>() { 1,2,2,3,4,3,3 };

// list contains anything for 3 times?
var found = list.FirstRepeatedTimes(3).Any();

It could potentially consume some more memory, but it enumerates the list at most once. Is this Linq? The way I wrote it, it yields exactly 1 element (the first found), or no element, and you can further compose on top of it if you want. You could use FirstOfDefault() instead of Any(), and have then the found element or 0 (or null if we deal with reference types). This way you have the choice.

It's just another way to see it.

于 2012-09-21T14:10:01.980 に答える
1

試す

return
    collection.Any(any => collection.Count(item => item.Equals(any)) == 3);
于 2012-09-21T12:17:03.840 に答える
1

アイテムを単独でグループ化し、いずれかのグループに 3 つのアイテムが含まれているかどうかを評価すると、期待どおりの結果が得られます。

private bool ContainsTriple<T>(IList<T> items){
    return items.GroupBy(i => i).Any(l => l.Count() == 3);
}
于 2012-09-21T12:26:58.950 に答える
0
    static void Main(string[] args)
    {
        List<string> col = new List<string>();

        col.Add("a");
        Console.WriteLine(Has_3(col));
        Console.ReadKey();
        col.Add("a");
        Console.WriteLine(Has_3(col));
        Console.ReadKey();
        col.Add("a");
        Console.WriteLine(Has_3(col));
        Console.ReadKey(); 
        col.Add("a");
        Console.WriteLine(Has_3(col));
        Console.ReadKey();
    }

    static bool Has_3(List<string> col)
    {
        return col.Count(x => x == "a").Equals(3);
    }
于 2012-09-21T12:20:46.537 に答える
0

私が最初に考えたのは、これはおそらく次のような Group() メソッドを使用して実行できるということでした:

var ints = new List<int>(new[] { 1, 2, 3, 4, 5, 6, 2, 2 });

var first = ints.GroupBy(n => n)
    .Select(g => new { g.Key, Count = g.Count() })
    .First(g => g.Count >= 3);

Console.WriteLine("Found {0} instances of {1}", first.Count, first.Key);

このスニペットは、3 つ以上の同じアイテムをチェックし、基準を満たす最初のアイテムを選択します。これを変更することをお勧めします。そして、整数ではなく特定のオブジェクトに適応させます。

于 2012-09-21T12:21:30.827 に答える
0

拡張機能は次のとおりです。

public static bool ContainsNTimes<T>(this IEnumerable<T> sequence, T element, int duplicateCount)
{
    if (element == null)
        throw new ArgumentNullException("element");
    if (!sequence.Any())
        throw new ArgumentException("Sequence must contain elements", "sequence");
    if (duplicateCount < 1)
         throw new ArgumentException("DuplicateCount must be greater 0", "duplicateCount");

    bool containsNTimes = sequence.Where(i => i.Equals(element))
                            .Take(duplicateCount)
                            .Count() == duplicateCount;
    return containsNTimes;
}

使用法:

var list = new List<int>() { 1,2,2,3,4,3,3 };

// list contains 2 for 3 times?
bool contains2ThreeTimes = list.ContainsNTimes(2, 3);

// any element in the list iscontained 3 times (or more)?
bool anyContains3Times = list.Any(i => list.ContainsNTimes(i, 3));

Console.WriteLine("List contains 2 for 3 times? " + contains2ThreeTimes); // false
Console.WriteLine("Any element in the list is contained 3 times (or more)? " + anyContains3Times); // true (3)

デモ: http://ideone.com/Ozk9v

遅延実行を使用するため、非常に効率的です。n 個の項目が見つかるまでシーケンスを列挙します。

于 2012-09-21T12:21:42.933 に答える