簡體   English   中英

從列表中選擇3個相同的項目

[英]Selecting 3 identical items from list

我需要查找列表中是否有3個相同的項目。

它應該使用重寫的.Equals()方法比較元素。 我嘗試了很多方法都失敗了。 它返回bool值還是項目本身都沒有關系。 每次添加新項目后都會調用該函數,因此,只要列表中有3個相同項目,檢測到該點的時間就無關緊要。

這可能微不足道,但是我對Linq的了解非常薄弱。

嘗試

return
    collection.Any(any => collection.Count(item => item.Equals(any)) == 3);

通過單獨對項目進行分組並評估是否有任何組恰好包含三個項目,您將收到預期的結果。

private bool ContainsTriple<T>(IList<T> items){
    return items.GroupBy(i => i).Any(l => l.Count() == 3);
}

為了更好地表達我的概念:

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

您可以這樣使用它:

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

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

它可能會消耗更多的內存,但是最多枚舉該列表一次。 這是Linq嗎? 按照我編寫它的方式,它僅產生1個元素(第一個找到的元素),或者不產生任何元素,並且您可以根據需要在其上進一步編寫。 您可以使用FirstOfDefault()代替Any() ,然后找到元素或0 (如果我們處理引用類型,則為null )。 這樣,您可以選擇。

這只是另一種看待方式。

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

我的第一個想法是,可以使用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個或更多相同的項目,並選擇了符合條件的第一個項目,您可能需要更改此項目。 並使其適應您的特定對象而不是整數。

這是擴展名:

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個項目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM