1

C# 練習 - 在陣列中找出連續重複出現項目

 1 year ago
source link: https://blog.darkthread.net/blog/find-repeated-item-group/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

C# 練習 - 在陣列中找出連續重複出現項目

calendar.svg 2022-12-06 10:03 PM comment.svg 1 eye.svg 2,311

專案出現的小需求:想在陣列挑出連續重複出現的項目,例如要從陣列 [A, B, B, C, X, C, C, B, B, D, D, D] 挑出 [B, B]、[C, C]、[B, B]、[D, D, D] 四個群組。

這題目的難易度用來暖身剛好,適合用 yield return 來解。

最後琢磨成品如下:

IEnumerable<IEnumerable<T>> FindRepeatItemGroups<T>(IEnumerable<T> list, Func<T, T, bool> areEqual)
{
    if (list.Any())
    {
        var grp = new List<T>() { list.First() };
        foreach (var item in list.Skip(1))
        {
            if (areEqual(grp.Last(), item))
            {
                grp.Add(item);
            }
            else
            {
                if (grp.Count() > 1)
                    yield return grp;
                grp = new List<T>() { item };
            }
        }
        if (grp.Count() > 1)
            yield return grp;
    }
}

函式接收 IEnumerable<T> 作為搜尋對象,是否重複出現由 Func<T, T, bool> 決定,呼叫時傳入 (a, b) => a.SomeProp == b.SomeProp 自訂比對條件。函式使用 List<T> 蒐集重複出現的物件,以 foreach 巡覽所有元素,遇到目前物件與 List<T> 保存物件不相等時,檢查 List<T> 個數若大於一,表示連續出現,yield return 傳回 List<T> 清空 List<T> 重新統計。

測試範例如下:

var raw = "A,B,B,C,X,C,C,B,B,D,D,D".Split(',');
var i = 1;
var items = raw.Select(o => new
{
    Id = i++,
    Code = o
}).ToArray();
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Source: ");
foreach (var item in items)
{
    Console.ForegroundColor = ConsoleColor.DarkGray;
    Console.Write($"{item.Id}.");
    Console.ForegroundColor = ConsoleColor.Yellow;
    Console.Write($"{item.Code} ");
}
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Cyan;
var grps = FindRepeatItemGroups(items, (a, b) => a.Code == b.Code);
foreach (var grp in grps)
{
    Console.Write($"Group of {grp.First().Code} :");
    Console.WriteLine($" {string.Join(", ", grp.Select(o => o.Id))}");
}
Console.ResetColor();

IEnumerable<IEnumerable<T>> FindRepeatItemGroups<T>(IEnumerable<T> list, 
        Func<T, T, bool> areEqual)
{
    if (list.Any())
    {
        var grp = new List<T>() { list.First() };
        foreach (var item in list.Skip(1))
        {
            if (areEqual(grp.Last(), item))
            {
                grp.Add(item);
            }
            else
            {
                if (grp.Count() > 1)
                    yield return grp;
                grp = new List<T>() { item };
            }
        }
        if (grp.Count() > 1)
            yield return grp;
    }
}

Fig1_638059323956943574.png

  • Posted in
  • C#

and has 1 comment

Comments

Post a comment

Comment
Name Captcha 74 - 12 =

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK