且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

c#将字符串转换为IEnumerable< T>

更新时间:2023-02-14 10:55:31

实际上,一个字符串是一个字符集合,因此当您使用 UniqueInOrder(AAAABBBCCDAABBB )你调用 UniqueInOrder< char> ,而不是 UniqueInOrder< string> 。因此,该方法的返回值也是 IEnumerble ,而不仅仅是字符串。 应该比较方法的返回值与一个字符集合,例如:

  CollectionAssert.AreEqual(new [] {'A' ,'B','C','D','A''B','Ä'},UniqueInOrder(...)); 

或更简单:

  CollectionAssert.AreEqual(expected.ToCharArray(),UniqueInOrder(...)); 

但即使如此,您的测试也会失败,因为 Distinct 会过滤掉所有重复项目。



当您想检查两个序列是否完全相同时,您可以使用 SequenceEqual 代替:

  var equal = firstColl.SequenceEqual(second); 

编辑:很明显,你试图删除序列中的所有双倍字符。您可以使用这个:

  public static IEnumerable< T> UniqueInOrder< T>(IEnumerable< T> iterable)其中T:IEquatable< T> 
{
T previous = default(T);
foreach(迭代中的var t)
{
if(!t.Equals(previous))
yield return t;
previous = t;


$ / code $ / pre

现在你可以调用它并与你的期望值进行比较输出,例如:

  var actual = new String(UniqueInOrder(AABBCCDDAABB)。ToArray()); 
var期望ABCDAB;
Assert.AreEqual(预计,实际);


I have this function:

public static IEnumerable<T> UniqueInOrder<T>(IEnumerable<T> iterable)  
{  
    return iterable.Distinct();  
}

This works with any IEnumerable except with a string, I must test it with this call:

Assert.AreEqual("ABCDAB", UniqueInOrder("AAAABBBCCDAABBB"));

The assert fail:

Expected is <System.String>, actual is <System.Linq.Enumerable+<DistinctIterator>c__Iterator10`1[System.Char]>
  Values differ at index [4]

I also tried something like:

public static IEnumerable<T> UniqueInOrder<T>(IEnumerable<T> iterable)
{
    return "abc";
}

But I have a compiler error:

Cannot implicitly convert type 'string' to 'System.Collections.Generic.IEnumerable<T>'

How is possible that I can call the function with a string but I can not return a string? The type is still the same IEnumerable< T >

Any idea? Thank you!

EDITED: Distinct() was wrong, I changed to this:

public static IEnumerable<T> UniqueInOrder<T>(IEnumerable<T> iterable)
{
    List<T> result = new List<T>();
    foreach (var c in iterable.ToList())            
        if (result.LastOrDefault() == null || !result.LastOrDefault().Equals(c))
            result.Add(c);              
    return result;
}

Now all the tests are passing! Thanks!

Actually a string is a collection of characters, thus when you use UniqueInOrder("AAAABBBCCDAABBB") you actuall call UniqueInOrder<char>, instead of UniqueInOrder<string>. Thus the return-value of the method will also be IEnumerble<char>, not just string.

So you should compare the methods return-value with a collection of characters, e.g.:

CollectionAssert.AreEqual(new[] { 'A', 'B', 'C', 'D', 'A' 'B', 'Ä' }, UniqueInOrder(...));

or easier:

CollectionAssert.AreEqual(expected.ToCharArray(), UniqueInOrder(...));

But even then your test will fail as Distinct will filter out all duplicates.

When you want to check if two sequences are completely identical you may use SequenceEqual instead:

var equal = firstColl.SequenceEqual(second);

EDIT: Obviously you´re trying to remove all just the doubled characters in a sequence. You may use this:

public static IEnumerable<T> UniqueInOrder<T>(IEnumerable<T> iterable) where T : IEquatable<T>
{
    T previous = default(T);
    foreach (var t in iterable)
    {
        if (!t.Equals(previous))
            yield return t;
        previous = t;
    }
}

Now you can call it and compare it with your expected output, e.g.:

var actual = new String(UniqueInOrder("AABBCCDDAABB").ToArray());
var expected "ABCDAB";
Assert.AreEqual(expected, actual);