Se requiere Funky LINQ (Parte 2)

I have a CSV string:

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";

The first 2 elements are ID's.

The second 2 indicate a row and column eg 1 Row 3 Columns. Each chunk of data has 4 elements in it so I would need to filter out 12 elements which would be: 29,P,6.74,11.23,07,P,5.25,14.29,08,P,6.89,16.92

After that the next elements are 2 and 5 eg 2 Rows 5 Columns. Again each chunk of data has 4 elements so I would need 40 elements and this would result in 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

The next elements are 1,1 eg 1 Row 1 Column so take 4 elements i.e. 111,P,7.26,13.79

The indicators (eg 1,3 & 2,5 & 1,1) could be different and so obviously the CSV length will be different. There may also be numerous sets of these indicators not just 3 in this example.

I already started using the Aggregate((x, y) => x * y) method to calculate how many we need but my code is not dynamic enough to account for more than 3 indicator sets

Is there a way to find these indicators and then return the correct number of elements from the correct position in the CSV string?

Aviso: I'm not restricting myself to a LINQ only solution. I just thought there maybe built in methods to handle this.

preguntado el 08 de noviembre de 11 a las 15:11

Why are you trying to navigate this parsing problem with Linq. Aren't you aware that people parsed just fine before Linq existed? -

Yup, fair enough point. I just thought it may be easier. I'm not wanting a definate LINQ solution. Whatever works. -

In that case, you're basically posting a "gimme the code" question. This should be closed. -

This does not really seem like a LINQ problem to me.. In this scenario it may be easier to read this string into an object structure you create so it is easier to work with. -

Because the length of the string is dynamic I'm not sure how I'd have be able to expose relevant properties in an object -

2 Respuestas

hmm, pseudo-code:

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

I'm guessing that you want to store the elements in a matrix, and that you want a list of matrices for your result, but this covers any number of pairs x,y and therefore any length input.

respondido 08 nov., 11:20

I have consulted with a colleague and have a working solution however I am open to whether it can be improved:

 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++;
            }

respondido 08 nov., 11:20

First thing comes in mind is using split, but it's time consuming if the string length is big, because string is immutable it takes too many memory (again if string size is big). - Saeed Amiri

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.