簡體   English   中英

唯一的順序 C#

[英]Unique in order C#

我在執行 CodeWars 的練習時遇到了一些麻煩。 我在另一個編譯器中制作了它,一切正常,但在 CodeWars 中存在 IEnumerable 錯誤,我不知道如何處理它們。

所以,這是練習:

實現函數unique_in_order ,它將序列作為參數並返回一個項目列表,其中沒有任何具有相同值的元素彼此相鄰並保留元素的原始順序。

例如:

 uniqueInOrder("AAAABBBCCDAABBB") == {'A', 'B', 'C', 'D', 'A', 'B'} uniqueInOrder("ABBCcAD") == {'A', 'B', 'C', 'c', 'A', 'D'} uniqueInOrder([1,2,2,3,3]) == {1,2,3}

我的解決方案:

using System.Collections.Generic;

public static class Kata {
    public static IEnumerable<T> UniqueInOrder<T>(IEnumerable<T> iterable) {

    var first = iterable[0];
    
    var uniques = new List<char>();

    uniques.Add(first);
    
    foreach(var item in iterable)
    {
        if (item == first)
        {
            continue;
        }
        first = item;
        uniques.Add(first);
    }

    var result = string.Join("", uniques);

   return result;
  }
}

我得到的錯誤:

src/Solution.cs(8,17): 錯誤 CS0021: 無法將 [] 索引應用於類型為“IEnumerable<T>”的表達式
src/Solution.cs(26,12): 錯誤 CS0029: 無法將類型“字符串”隱式轉換為“System.Collections.Generic.IEnumerable<T>”

為什么不使用yield return關鍵字? 他們很方便。

class Program
{
    public static IEnumerable<T> UniqueInOrder<T>(IEnumerable<T> sequence)
    {
        T prev = default!;
        bool hasPrev = false;

        foreach (T item in sequence)
        {
            if ((!hasPrev && (hasPrev = true)) || !EqualityComparer<T>.Default.Equals(item, prev))
            {
                yield return item;
            }

            prev = item;
        }
    }

    static void Main(string[] args)
    {
        Console.WriteLine(new string(UniqueInOrder("AAAABBBCCDAABBB").ToArray()));
        Console.WriteLine(new string(UniqueInOrder("ABBCcAD").ToArray()));
    }
}

首先,交換var first = iterable[0]; 使用var first = iterable.First()
您不能在IEnumerable上使用索引。

其次,您正在使用字符List<char>(); 存儲類型T 使用List<T>
您不能將一般類型存儲為特定類型。

第三,為什么最后要使用String.Join() ,為什么不只返回唯一值?
List也是一個IEnumerable

你已經接近解決方案了。 讓我們來看看一些錯誤:

在這個語句中: var first = iterable[0]; 您無法通過索引訪問 IEnumerable 項目。 IEnumerables 並不是真正的列表或集合。 如果您願意,我可以對此進行擴展。

您可以通過以下方式訪問它:

var first = iterable.First();

在這個語句中: var uniques = new List<char>(); ,您正在創建一個 char 列表來保存 IEnumerable 的 itens,盡管 itens 是泛型類型T 正確的形式是:

var uniques = new List<T>();

if (item == first) ,您不能使用==比較兩個不受約束的泛型類型。

您可以使用item.Equals(first)EqualityComparer<T>.Default.Equals(item, first)

最后,您將列表轉換為字符串並返回它。 盡管您的方法的返回類型不是字符串,而是IEnumerable<T>

代替

 var result = string.Join("", uniques);

 return result;

您可以擺脫result ,並返回您的列表:

return uniques;

通過這些修復,您的代碼將變為:

public static IEnumerable<T> UniqueInOrder<T>(IEnumerable<T> iterable) 
{
    var first = iterable.First();
    
    var uniques = new List<T>();

    uniques.Add(first);
    
    foreach(var item in iterable)
    {
        if (item.Equals(first))
        {
            continue;
        }
        first = item;
        uniques.Add(item);
    }

    return uniques;
}

這已經有效了。 但是,可以通過刪除first變量的賦值並將其集成到更一般的情況來簡化此代碼。 您還可以刪除uniques列表並一次生成每個項目。

我提出的最終解決方案如下:

public static IEnumerable<T> UniqueInOrder<T>(IEnumerable<T> iterable) 
{
    var current = default(T);
    
    foreach(var item in iterable)
    {
        if (item.Equals(current))
            continue;
            
        current = item;
        
        yield return item;
    }
}

暫無
暫無

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

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