【问题标题】:Funky LINQ Required (Part 2)需要时髦的 LINQ(第 2 部分)
【发布时间】:2011-11-08 15:45:07
【问题描述】:

我有一个 CSV 字符串:

string data = "G9999999990001800002777107050,G9999999990002777107HMNLAQKPRLLHRAQRWJ010,1,3,29,P,6.74,11.23,07,P,5.25,14.29,08,P,6.89,16.92,2,5,052,U,4.78,31.04,095,O,9.59,27.63,076,P,3.85,16.50,094,P,4.84,18.30,093,O,8.28,26.90,062,P,4.64,16.00,061,P,2.84,12.87,090,O,7.90,20.83,050,P,3.36,16.59,057,B,12.05,34.46,1,1,111,P,7.26,13.79";

前 2 个元素是 ID。

第二个 2 表示一行和一列,例如 1 Row 3 Columns。每个数据块中有 4 个元素,所以我需要过滤掉 12 个元素,它们是:29,P,6.74,11.23,07,P,5.25,14.29,08,P,6.89,16.92

之后的下一个元素是 2 和 5,例如 2 行 5 列。同样,每个数据块都有 4 个元素,所以我需要 40 个元素,这将导致 052,U,4.78,31.04,095,O,9.59,27.63,076,P,3.85,16.50,094,P,4.84,18.30,093,O,8.28,26.90,062,P,4.64,16.00,061,P,2.84,12.87,090,O,7.90,20.83,050,P,3.36,16.59,057,B,12.05,34.46

接下来的元素是 1,1 例如 1 Row 1 Column 所以取 4 个元素,即 111,P,7.26,13.79

指标(例如 1,3 & 2,5 & 1,1)可能不同,因此显然 CSV 长度会不同。这些指标也可能有很多组,而在这个例子中不仅仅是 3 个。

我已经开始使用Aggregate((x, y) => x * y) 方法来计算我们需要多少,但我的代码不够动态,无法考虑超过 3 个指标集

有没有办法找到这些指标,然后从 CSV 字符串中的正确位置返回正确数量的元素?

请注意:我并没有将自己限制为仅使用 LINQ 的解决方案。我只是认为可能有内置的方法来处理这个问题。

【问题讨论】:

  • 您为什么要尝试使用 Linq 解决这个解析问题。你不知道在 Linq 存在之前人们解析得很好吗?
  • 是的,很公平。我只是认为这可能更容易。我不想要一个明确的 LINQ 解决方案。什么都行。
  • 在这种情况下,您基本上是在发布“给我代码”问题。这应该关闭。
  • 这对我来说似乎不是一个 LINQ 问题。在这种情况下,将这个字符串读入您创建的对象结构可能更容易,因此更容易使用。
  • 因为字符串的长度是动态的,所以我不确定如何在对象中公开相关属性

标签: c# .net linq c#-4.0 .net-4.0


【解决方案1】:

嗯,伪代码:

read first two IDs
int c = position of second comma
while c <= length of string
    int x = parse number after c
    int y = parse number after x
    set c = position of y + 1
    int[][] m = new int[x][y]
    for (i=0; i<x; i++)
        for (j=0; j<y; j++)
            m[i][j] = parse 4 elements after c
            move c to end of m[i][j]
    add m to list of results

我猜你想将元素存储在一个矩阵中,并且你想要一个矩阵列表作为你的结果,但这涵盖了任意数量的对 x,y,因此是任意长度的输入。

【讨论】:

    【解决方案2】:

    我已经咨询了一位同事并有一个可行的解决方案,但我对是否可以改进持开放态度:

     public class Data
            {
                public string Index { get; set; }
                public string Letter { get; set; }
            }
    
    string data = "G9999999990001800002777107050,G9999999990002777107HMNLAQKPRLLHRAQRWJ010,1,3,29,P,6.74,11.23,07,P,5.25,14.29,08,P,6.89,16.92,2,5,052,U,4.78,31.04,095,O,9.59,27.63,076,P,3.85,16.50,094,P,4.84,18.30,093,O,8.28,26.90,062,P,4.64,16.00,061,P,2.84,12.87,090,O,7.90,20.83,050,P,3.36,16.59,057,B,12.05,34.46,1,1,111,P,7.26,13.79";
    
                var elements = data.Split(',');
    
                int counter = 1;
                int startIndex = 2;
                int dataBlock=0;
                Dictionary<int, List<Data>> result = new Dictionary<int,List<Data>>();
    
                while(elements.Length > startIndex)
                {
                    dataBlock = int.Parse(elements[startIndex]) * int.Parse(elements[startIndex+1]);
                    startIndex +=2;
                    for(int i=0;i<dataBlock;i++)
                    {
                        Data d = new Data(){Index = elements[startIndex], Letter = elements[startIndex+1]};
                        if (result.ContainsKey(counter))
                            result[counter].Add(d);
                        else
                        {
                            result.Add(counter, new List<Data>());
                            result[counter].Add(d);
                        }
    
                        startIndex+=4;
                    }
                    counter++;
                }
    

    【讨论】:

    • 首先想到的是使用split,但是如果字符串长度很大,它会很耗时,因为字符串是不可变的,它会占用太多内存(如果字符串很大)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多