[英]Returning a string from an IEnumerable<T>function
I am probably doing something wrong but I'm trying to do this Kata on Codewars我可能做错了什么,但我正在尝试在 Codewars 上做这个 Kata
This is my current code below.这是我下面的当前代码。
public static class Kata
{
public static IEnumerable<T> UniqueInOrder<T>(IEnumerable<T> arr)
{
Type t = typeof(T);
if (t == typeof(string))
return (IEnumerable<T>)String.Join("",arr.Distinct()).AsEnumerable();
return arr.Distinct().ToArray();
}
}
The unit tests for this kata are expecting an input of "AAAABBBCCDAABBB" to be returned as "ABCDAB".此 kata 的单元测试期望输入“AAAABBBCCDAABBB”作为“ABCDAB”返回。
My code above is failing due to this error Expected is <System.String>, actual is <System.Char[6]>
由于此错误,我上面的代码失败Expected is <System.String>, actual is <System.Char[6]>
If I try to return a string I get this error: error CS0029: Cannot implicitly convert type 'string' to 'System.Collections.Generic.IEnumerable<T>'
如果我尝试返回一个字符串,我会收到此错误: error CS0029: Cannot implicitly convert type 'string' to 'System.Collections.Generic.IEnumerable<T>'
I'm lost as how I can return the expected string if I can't return a string (and a char array fails)如果我无法返回字符串(并且 char 数组失败),我会迷失如何返回预期的字符串
Thanks谢谢
You can implement it like this (since you've used <T>
let implement general case solution with custom comparer
):您可以像这样实现它(因为您已经使用<T>
让我们使用自定义comparer
实现一般案例解决方案):
public static IEnumerable<T> UniqueInOrder<T>(IEnumerable<T> source,
IEqualityComparer<T> comparer = null) {
if (null == source)
throw new ArgumentNullException(nameof(source));
comparer ??= EqualityComparer<T>.Default;
bool first = true;
T prior = default; // default: let compiler be happy
foreach (T item in source)
if (first || !comparer.Equals(item, prior)) {
prior = item;
first = false;
yield return item;
}
}
Here we just check if current item
is equal to prior
.这里我们只检查当前item
是否等于prior
项。
Demo:演示:
string source = "AAAABBBCCDAABBB";
string result = string.Concat(UniqueInOrder(source));
Console.Write(result);
Outcome:结果:
ABCDAB
Edit: Please, note that Distinct()
in the编辑:请注意Distinct()
在
arr.Distinct()
removes duplicates in the entire arr
, that's why you'll get only 4 distinct characters:删除整个arr
中的重复项,这就是为什么你只会得到 4 个不同的字符:
AAAABBBCCDAABBB -> ABCD
Distinct()
In the given problem we have a weaker condition: current item must not be equal to prior.在给定的问题中,我们有一个较弱的条件:当前项目不能等于先前项目。
This should do it:这应该这样做:
public static IEnumerable<T> UniqueInOrder<T>(IEnumerable<T> iterable)
{
using var e = iterable.GetEnumerator();
bool EnumeratorActive = e.MoveNext(); //start iterating
while (EnumeratorActive)
{
// set and yield the current value
T cur = e.Current;
yield return cur;
// keep advancing while the iterator is active and additional values match the current val
while(cur.Equals(e.Current) && (EnumeratorActive = e.MoveNext()))
{} //empty body intentional
}
}
It uses a pattern of nested while loops called Control/Break that still runs in linear time (because only the inner loop advances).它使用一种称为Control/Break的嵌套 while 循环模式,该模式仍以线性时间运行(因为只有内部循环在前进)。
Here's a reduced version without the extra explainers:这是一个没有额外解释器的简化版本:
public static IEnumerable<T> UniqueInOrder<T>(IEnumerable<T> iterable)
{
using var e = iterable.GetEnumerator();
bool EnumeratorActive = e.MoveNext();
while (EnumeratorActive)
{
T cur = e.Current;
yield return cur;
while(cur.Equals(e.Current) && (EnumeratorActive = e.MoveNext()));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.