Home > Back-end >  In C# trying to split a comma delimited list into an object
In C# trying to split a comma delimited list into an object

Time:01-19

I haven't seen any examples like this, so hopefully this isn't a duplicate. I have a process that's given this string:

Line1=LineOne;Line2=LineTwo;City=City;State=StateOrProvidence;Zip=PostalCode

I need to turn this into an AddressField object:

public class AddressField 
{
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}

I'm not finding a simple way to do this. Trying to split it into a dictionary or list, but nothing is working as easily as I hoped. Also it has to be in DotNet Framework 4.6.2 without any extra add-ins.
Any suggestions? Thanks.

CodePudding user response:

One idea would be to create a static method on the class that returns an instance of the class based on an input string. You could split the string on the semi-colon character, and then split each result on the equals sign, ending up with the key-value pairs for each property. Then you could use a switch statement to parse the pairs and set the appropriate property values:

public class AddressField
{
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }

    public static AddressField FromString(string input)
    {
        if (input == null) return null;

        AddressField result = new AddressField();

        foreach(var kvp in input.Split(';'))
        {
            var parts = kvp.Split('=');
            if (parts.Length == 2)
            {
                switch(parts[0])
                {
                    case "Line1":
                        result.Line1 = parts[1];
                        break;
                    case "Line2":
                        result.Line2 = parts[1];
                        break;
                    case "City":
                        result.City = parts[1];
                        break;
                    case "State":
                        result.State = parts[1];
                        break;
                    case "Zip":
                        result.Zip = parts[1];
                        break;
                }
            }
        }

        return result;
    }
}

Example usage:

var addressField = AddressField.FromString("Line1=LineOne;Line2=LineTwo;City=City;State=StateOrProvidence;Zip=PostalCode");

CodePudding user response:

The simple solution

Create a Parse() function to manually assign values

public class AddressField
{
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }

    public override string ToString()
    {
        return $"Line1={Line1};Line2={Line2};City={Line1};State={State};Zip={Zip}";
    }

    public static AddressField Parse(string line)
    {
        AddressField result = new AddressField();
        string[] parts = line.Split(';');
        foreach (var item in parts)
        {
            string[] values = item.Split('=');

            switch (values[0])
            {
                case "Line1":
                    result.Line1 = values[1];
                    break;
                case "Line2":
                    result.Line2 = values[1];
                    break;
                case "City":
                    result.City = values[1];
                    break;
                case "State":
                    result.State = values[1];
                    break;
                case "Zip":
                    result.Zip = values[1];
                    break;
            }
        }
        return result;
    }
}

and test it with

static void Main(string[] args)
{
    string input = "Line1=LineOne;Line2=LineTwo;City=City;State=StateOrProvidence;Zip=PostalCode";
    AddressField address = AddressField.Parse(input);
    Console.WriteLine(address);
}

Of course, a lot of checks are missing here to create robust code. The above is just for illustrative purposes.

The Dynamic Solution

You can use a ExpandObject to build a type on the go as you parse values, and then convert into a AddressField.

public class AddressField
{
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }

    public override string ToString()
    {
        return $"Line1={Line1};Line2={Line2};City={Line1};State={State};Zip={Zip}";
    }

    public static AddressField Parse(string line)
    {
        dynamic obj = new ExpandoObject();
        IDictionary<string, object> properties = obj;

        string[] parts = line.Split(';');
        foreach (var item in parts)
        {
            string[] values = item.Split('=');
            properties[values[0]] = values[1];
        }

        return new AddressField()
        {
            Line1 = obj.Line1,
            Line2 = obj.Line2,
            City = obj.City,
            State = obj.State,
            Zip = obj.Zip,
        };
    }
}
  •  Tags:  
  • c#
  • Related