c# - 聚合 IEnumerable 中的一系列连续 block

标签 c# ienumerable aggregate

过于简化、做作的问题

我有一个可枚举的实例,它可以包含一系列连续的元素,以及一些其他元素与它们相互分散。一个简单的例子

var items = new[]
            {"1","1","1","1","1","varX","1","1","1","1","varY","1","1"};

如您所见,字符串 1 重复出现,然后不时出现其他内容(非常容易识别)。可以说我想以形成可枚举的方式聚合

var aggregated = new[]
          { "11111", "varX", "1111", "varY","11"};

这显然只是“所有 1 的连接”,后跟“var”,然后是下一组连接的 1。等

不要太在意字符串细节;将“1”视为对象 Word 的实例,将“var”视为对象 Variable 的实例。现在我想将 Word 连接在一起(组成一个句子)并以不同方式处理 Variable

我将如何着手编写该聚合,使用 LINQ 还是简单的老式 foreach?

略微简化,同样的问题

我有一个可枚举的“ token ”列表。只有两种类型的 token ,都继承自基础 token :

public abstract class Token{}
public class WordToken : Token {}
public class VariableToken : Token {}

字符串:

Hello world {varX} how are you {varY} bye

将被我的代码标记为以下可枚举

  var tokens = new[]
    { 
       WordToken, 
       WordToken, 
       VariableToken,  
       WordToken,  
       WordToken,  
       WordToken,  
       VariableToken,  
       WordToken
    };

我想把它变成

var newList = new [] 
    {
       FragmentToken, 
       VariableToken,  
       FragmentToken,  
       VariableToken,  
       FragmentToken
     };

FragmentToken 是刚刚连接在一起的所有单词

显而易见的第一步是聚合要制作的原始列表

var step = new[]
    { 
          new[]{WordToken, WordToken}, 
          new[]{VariableToken},
          new[]{ WordToken, WordToken, WordToken}, 
          new[]{VariableToken}, 
          new[]{WordToken}
    };

然后我可以轻松地进行下一步,但我无法理解如何进行这第一步。

最佳答案

这是否接近您想要的解决方案?

public abstract class Token : IComparable
{
    public int CompareTo(object obj)
    {
        if (obj == null)
        {
            return -1;
        }
        return GetType().FullName.CompareTo(obj.GetType().FullName);
    }
}
public class WordToken : Token { }
public class VariableToken : Token { }

public static class ListExtensions
{
    public static IEnumerable<IEnumerable<TEntity>> JoinRepeatedValues<TEntity>(this IEnumerable<TEntity> collection)
        where TEntity : IComparable
    {
        var joinedRepeatedValuesCollection = new List<List<TEntity>>();
        var lastValue = default(TEntity);
        foreach (var item in collection)
        {
            if (item.CompareTo(lastValue) != 0)
            {
                joinedRepeatedValuesCollection.Add(new List<TEntity> { item });
            }
            else
            {
                var lastAddedValue = joinedRepeatedValuesCollection.Last();
                lastAddedValue.Add(item);
            }
            lastValue = item;
        }
        return joinedRepeatedValuesCollection;
    }

}
class Program
{
    static void Main(string[] args)
    {
        var tokens = new Token[]
                            {
                                new WordToken(),
                                new WordToken(),
                                new VariableToken(),
                                new WordToken(),
                                new WordToken(),
                                new WordToken(),
                                new VariableToken(),
                                new WordToken()
                            };

        var joinedValues = tokens.JoinRepeatedValues();
        var items = new[] { "1", "1", "1", "1", "1", "varX", "1", "1", "1", "1", "varY", "1", "1" }.JoinRepeatedValues();
    }
}

关于c# - 聚合 IEnumerable 中的一系列连续 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16178641/

相关文章:

sql - SQL区分和计数

c# - ASP.NET MVC 应用程序有 SecurityException

c# - ReadOnlySequence – 切片到给定的 SequencePosition + 1

c# - 使用 LINQ 使用现有数组对列表进行排序

.net - 如何使用 F# 的 Seq.cast 避免 "Value restriction"错误?

具有聚合功能的 MySQL GROUP BY DateTime

c# - BackgroundWorker 在 foreach 循环期间从 DAL 返回值

c# - 将 IEnumerable 转换为 EntitySet

C# 简单列表显示的问题

r - dplyr - 聚合不正确?