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