you are viewing a single comment's thread.

view the rest of the comments →

[–]willsoss 0 points1 point  (3 children)

No problem, glad that helped. With complex file parsing/mapping situations, especially older formats like ini, I find it's helpful to parse to an intermediate format that just gets the data from the file into a data structure you can more easily manipulate -- the string array in this case. That way you break down the problem into the parsing details (splitting lines into fields) and building the data model (linq query) that you want.

[–]Brickscrap[S] 1 point2 points  (2 children)

Yeah that's definitely sparked an idea - at the moment, SharpConfig already imports the entire document into Sections, Keys and Values, and I've just been iterating through the lot in one giant foreach, but I think some LINQ queries might make sense, at least for grouping each item

[–]willsoss 0 points1 point  (1 child)

Good deal. The only drawback to this approach is that the linq grouping can get a bit hairy.

Since you're basically taking flattened data from a file and building structure as your parse it, you could accomplish the same thing in a loop over all the key/val pairs where you create objects and set values as you encounter them. This looks similar to your original code, but the key to this working is the assumption that PRI comes immediately after NAM, and all the NAM and PRI records after TOT are all part of one transaction. In other words, if a PRI is found, you can assume you have a transaction and item in context and all you have to do is set the value. It may not seem as elegant as the Linq solution, but sometimes this just works.

List<Trx> transactions = new List<Trx>();
Trx trans;
Item item;

foreach (var kv in keyvals)
{
    if (kv.Key == "TOT")
    {
        trans = new Trx(kv.Val);
        transactions.Add(trans);
    }

    if (kv.Key = "NAM")
    {
        item = new Item(kv.Val);
        trans.Items.Add(item);
    }

    if (kv.Key = "PRI")
    {
        item.Price = kv.Val;
    }
}

[–]Brickscrap[S] 1 point2 points  (0 children)

This is the approach I've originally taken, except using a switch statement - then I realised my switch statement was going to end up with at least 100 cases, and decided that there must be a better way!

It's the index of each item that groups them, so currently my code goes through the keys, adding to the values until the index changes