[英]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.