繁体   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