[英]Unique in order C#
I have some trouble with executing an exercise from CodeWars.我在执行 CodeWars 的练习时遇到了一些麻烦。 I made it in another compilator and everything works as it has to be but in CodeWars there are IEnumerable errors and I have no idea how to deal with them.
我在另一个编译器中制作了它,一切正常,但在 CodeWars 中存在 IEnumerable 错误,我不知道如何处理它们。
So, here is the exercise:所以,这是练习:
Implement the function
unique_in_order
which takes as argument a sequence and returns a list of items without any elements with the same value next to each other and preserving the original order of elements.实现函数
unique_in_order
,它将序列作为参数并返回一个项目列表,其中没有任何具有相同值的元素彼此相邻并保留元素的原始顺序。For example:
例如:
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}
My solution:我的解决方案:
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;
}
}
Errors I get:我得到的错误:
src/Solution.cs(8,17): error CS0021: Cannot apply indexing with [] to an expression of type 'IEnumerable<T>'
src/Solution.cs(8,17): 错误 CS0021: 无法将 [] 索引应用于类型为“IEnumerable<T>”的表达式
src/Solution.cs(26,12): error CS0029: Cannot implicitly convert type 'string' to 'System.Collections.Generic.IEnumerable<T>'src/Solution.cs(26,12): 错误 CS0029: 无法将类型“字符串”隐式转换为“System.Collections.Generic.IEnumerable<T>”
Why don't you use yield return
keyword?为什么不使用
yield return
关键字? They're handy.他们很方便。
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()));
}
}
Firstly, exchange var first = iterable[0];
首先,交换
var first = iterable[0];
with var first = iterable.First()
.使用
var first = iterable.First()
。
You can't use indexing on IEnumerable
.您不能在
IEnumerable
上使用索引。
Secondly you are using list of chars List<char>();
其次,您正在使用字符
List<char>();
to store type T
.存储类型
T
。 Use List<T>
.使用
List<T>
。
You can't store general type as specific.您不能将一般类型存储为特定类型。
Thirdly, why you are using String.Join()
at the end, why not just return uniques?第三,为什么最后要使用
String.Join()
,为什么不只返回唯一值?
List
is also an IEnumerable
. List
也是一个IEnumerable
。
You were close to a solution.你已经接近解决方案了。 Let's run through some errors:
让我们来看看一些错误:
In this statement: var first = iterable[0];
在这个语句中:
var first = iterable[0];
you can't access an IEnumerable item via indexing.您无法通过索引访问 IEnumerable 项目。 IEnumerables aren't really lists or collections.
IEnumerables 并不是真正的列表或集合。 I can expand on that if you'd like.
如果您愿意,我可以对此进行扩展。
You could access it through:您可以通过以下方式访问它:
var first = iterable.First();
In this statement: var uniques = new List<char>();
在这个语句中:
var uniques = new List<char>();
, you're creating a list of char to hold the itens of your IEnumerable, although the itens are of generic type T
. ,您正在创建一个 char 列表来保存 IEnumerable 的 itens,尽管 itens 是泛型类型
T
。 The correct form is:正确的形式是:
var uniques = new List<T>();
In the line if (item == first)
, you can't compare two unconstrained generic types using ==
.在
if (item == first)
,您不能使用==
比较两个不受约束的泛型类型。
You can either use item.Equals(first)
or EqualityComparer<T>.Default.Equals(item, first)
.您可以使用
item.Equals(first)
或EqualityComparer<T>.Default.Equals(item, first)
。
Lastly, you're transforming your list in a string and returning it.最后,您将列表转换为字符串并返回它。 Although the return type of your method is not a string, but rather an
IEnumerable<T>
.尽管您的方法的返回类型不是字符串,而是
IEnumerable<T>
。
Instead of代替
var result = string.Join("", uniques);
return result;
You can get rid of result
, and return your list:您可以摆脱
result
,并返回您的列表:
return uniques;
With these fixes, your code becomes:通过这些修复,您的代码将变为:
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;
}
Which already works.这已经有效了。 However, this code could be simplified by removing the assignment of the
first
variable and integrating it to a more general case.但是,可以通过删除
first
变量的赋值并将其集成到更一般的情况来简化此代码。 You could also remove the uniques
list and yield each item at a time.您还可以删除
uniques
列表并一次生成每个项目。
My proposed final solution is as follows:我提出的最终解决方案如下:
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.