簡體   English   中英

使用LINQ計算列表中項目的出現次數

[英]Count Occurrences of an Item in a List using LINQ

我試圖使用LINQ計算列表中項目的出現次數,

我有以下架構 -

用戶(提供的所有條目),計數(待計算)

伯爵應該像 -

在此輸入圖像描述

我想不出一個優雅的解決方案。

甚至只能使用LINQ嗎? 如果沒有,我們如何使用LINQ和一些C#代碼實現這一點。

你可以通過循環和Enumerable.Take的組合來做到這一點,像:

for (int i = 0; i < list.Count; i++)
{
    //Get count of current element to before:
    int count = list.Take(i+1)
                    .Count(r => r.UserName == list[i].UserName);
    list[i].Count = count;
}

您的list定義為:

List<User> list = new List<User>
    {
        new User{UserName = "A"},
        new User{UserName = "B"},
        new User{UserName = "A"},
        new User{UserName = "A"},
        new User{UserName = "B"},
        new User{UserName = "A"},
        new User{UserName = "C"},
        new User{UserName = "A"},

    };

User類:

public class User
{
    public string UserName { get; set; }
    public int Count { get; set; }
}

稍后您可以打印輸出,如:

foreach (var item in list)
{
    Console.WriteLine("UserName: {0}, Running Total: {1}", item.UserName, item.Count);
}

你會得到:

UserName: A, Running Total: 1
UserName: B, Running Total: 1
UserName: A, Running Total: 2
UserName: A, Running Total: 3
UserName: B, Running Total: 2
UserName: A, Running Total: 4
UserName: C, Running Total: 1
UserName: A, Running Total: 5

可以用LINQ完成嗎? 可能不容易。 可以用你自己的擴展方法很容易地完成嗎? 當然(我實際上並沒有嘗試編譯和運行代碼,所以我不能保證它會起作用,但它絕對是一個很好的起點):

public static IEnumerable<Tuple<T, int>> RunningTotal<T>(this IEnumerable<T> source)
{
    var counter = new Dictionary<T, int>();

    foreach(var s in source)
    {
        if(counter.ContainsKey(s))
        {
            counter[s]++;
        }
        else
        {
            counter.Add(s, 1);
        }

        yield return Tuple.Create(s, counter[s]);
    }
}

你可以這樣做而不需要像這樣重復迭代這套: -

        var values = "ABAABCA".ToArray();

        var counts = new Dictionary<char, int>();

        var counter = values.Select(ch => 
            { 
                int count = counts[ch] = counts.ContainsKey(ch) ? counts[ch] + 1 : 1;
                return new {ch, count}; 
            });

        foreach (var c in counter)
            Console.WriteLine(c.ch + " -> " + c.count);

我是用Select做的。 我正在編寫一個同步功能,它可以從魔獸世界API中獲取物品,某些物品不再在API上,即使它們在技術上仍然在游戲中。 由於我按照拍賣行上市次數的順序同步物品,因此會被這些物品卡住。

我創建了一個壞項ID列表。 如果該項目不同步,我將其添加到列表中。 如果它無法同步3次,我想跳過該項目。 我用以下代碼完成了這個:

private int[] GetBadItemList()
{
    var ids = from i in _badItemIDs
              where _badItemIDs.Select(curItem => curItem.Equals(i)).Count() >= MAX_ITEM_TRYS
              select i;
    return ids.ToArray();
}

暫無
暫無

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

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