tags:

views:

77

answers:

2

I have a bunch of data in pipe-delimited format, where odd entries are index numbers, and even entries are the data e.g.

1|cat|2|dog|3|manatee|4||5|gerbil|6|etc

(note occasional missing values)

and I'm wondering if there is a nice .NET type way of turning this into a class pet with id and name parameters.

I've got some code which does a String.Split and iterates over the array, scraping together objects, but it looks more like I'm writing PL/SQL than C#... I'm sure there is a way of doing this in a single line of Linq or something - can anyone tell me the 'right' way to do this?

Thanks

+3  A: 

You can use the TextFieldParser class to handle the parsing of the string into fields (I know it's a VB class, but you can access it from C#). Then just set alternating fields to your new objects.

Here's the example from MSDN, changed into C#:

using (Microsoft.VisualBasic.FileIO.TextFieldParser MyReader = 
       new Microsoft.VisualBasic.FileIO.TextFieldParser("C:\\testfile.txt")) 
   { 
        MyReader.TextFieldType = FileIO.FieldType.Delimited; 
        MyReader.SetDelimiters(","); 
        string[] currentRow = null; 
        while (!MyReader.EndOfData) 
        { 
            try 
            { 
                currentRow = MyReader.ReadFields(); 
                string currentField = null; 
                foreach (var currentField in currentRow) 
                { 
                    //set values for your object here
                } 
            } 
            catch (Microsoft.VisualBasic.FileIO.MalformedLineException ex) 
            { 
              //handle the exception
            } 
        } 
    } 
jball
Thank you for your answer; is TextFieldParser superior to String.Split in this situation? What I'm really looking for is a nice .NET way to set values based on alternate items. I've posted my solution in another answer, but I don't feel it is a very 'clean' way of doing it.
Colin Pickard
I'm pretty sure that there's probably some Linq way of doing it, but not being that familiar with Linq I don't know if it would be cleaner than what you've got or using TextFieldParser. The advantages to TextFieldParser are all in the fact that it handles the parsing and all the weird cases robustly (which you don't seem to have many (any?) of in your case, but could come up). Anything you roll on your own is going to take a lot of work before it's as robust as the TextFieldParser.
jball
A: 

This is how I did it, which works, but doesn't seem very '.NET' way of doing it...

public List<Pet> CreatePets(String PetData)
{
     List<Pet> PetList = new List<Pet>();
     string[] PetArray = PetData.Split(new char[]{'|'}, StringSplitOptions.None);
     for (int i = 0; i < PetArray.Count(); i += 2)
     {
         Pet NewPet= new Pet(Convert.ToInt32(PetArray[i]), PetArray[i+1]);
         PetList.Add(Field);
     }                
     return PetList;
}
Colin Pickard
I think this is probably in many ways as good as the TextFieldParser. A couple of comments - your loop condition should be `i < PetArray.Count() - 1` in case there's an orphan at the end, otherwise you are likely to get ArrayOutOfBounds exceptions. Also, I would test `PetArray[i]` before calling `Convert.ToInt32` (or use `Int32.TryParse()` instead) in case the elements are out of order.
jball