ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c#-使用linq聚合文本文件内容,以便将它们分组

2019-12-11 03:06:26  阅读:296  来源: 互联网

标签:aggregate linq c


给出以下查询.

var query = files
            .SelectMany(file => File.ReadAllLines(file))
            .Where(_ => !_.StartsWith("*"))
            .Select(line => new {
                Order = line.Substring(32, 7),
                Delta = line.Substring(40, 3),
                Line = new String[] { line }
            });

显然,这将产生具有以下属性的对象列表:顺序:字符串,增量:字符串和线:字符串[]

我有一个看起来像这样的物品清单.

{ 1, 'A', {'line1'} }, 
{ 1, 'A', {'line2'} }, 
{ 2, 'B', {'line3'} }, 
{ 1, 'B', {'line4 } }

是否可以使用Linq聚合或类似的功能构造在收集线的同时将所有相邻的Order和Delta组合收集在一起.

这样聚合就是包含所有“行”的项目列表

{ 1, 'A', {'line1', 'line2'} }
{ 2, 'B', {'line3'} }
{ 1, 'B', {'line4'} }

由于聚合顺序地进行迭代,因此应该有可能收集所有具有相同字段的相邻行.

循环很容易做到,但我正在尝试使用一组lambda来实现.

解决方法:

您将需要GroupBy的以下变体:

public static class EnumerableExtensions
{
    public class AdjacentGrouping<K, T> : List<T>, IGrouping<K, T>
    {
        public AdjacentGrouping(K key) { Key = key; }
        public K Key { get; private set; }
    }

    public static IEnumerable<IGrouping<K, T>> GroupByAdjacent<T, K>(
                            this IEnumerable<T> sequence, Func<T, K> keySelector)
    {
        using (var it = sequence.GetEnumerator())
        {
            if (!it.MoveNext())
                yield break;
            T curr = it.Current;
            K currKey = keySelector(curr);
            var currentCluster = new AdjacentGrouping<K, T>(currKey) { curr };
            while (it.MoveNext())
            {
                curr = it.Current;
                currKey = keySelector(curr);
                if (!EqualityComparer<K>.Default.Equals(currKey, currentCluster.Key))
                {
                    // start a new cluster
                    yield return currentCluster;
                    currentCluster = new AdjacentGrouping<K, T>(currKey);
                }
                currentCluster.Add(curr);
            };
            // currentCluster is never empty
            yield return currentCluster;
        }
    }
}

具有此相邻分组,您的代码可以与Chris’s answer中的相同:

var query = files
    .SelectMany(file => File.ReadAllLines(file))
    .Where(_ => !_.StartsWith("*"))
    .Select(line => new
    {
        Order = line.Substring(32, 7),
        Delta = line.Substring(40, 3),
        Line = new String[] { line }
    })
    .GroupByAdjacent(o => new { o.Order, o.Delta })
    .Select(g => new { g.Key.Order, g.Key.Delta, Lines = g.Select(o => o.Line).ToList() });

免责声明:GroupByAdjacent函数来自我自己的宠物项目,未从任何地方复制.

标签:aggregate,linq,c
来源: https://codeday.me/bug/20191211/2106061.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有