mko
mko

Reputation: 7335

How to convert List to a string and back

I retrieved a list of users from database, something like

List<User> users = <..list of users from db...> 

Name, LastName, DateOfBirth //multidimensional array??

Now I want to store this list as a string and I want be able to reuse it i.e.

string strUsers = users.ToArray().ToString();

How to recreate a list of users from strUsers?

Is it possible?

Upvotes: 2

Views: 5920

Answers (4)

Jaanus Varus
Jaanus Varus

Reputation: 3573

If you have a lot of users and a lot of columns, it would be better to write your own custom converter class.

public static class UsersConverter
{
    // Separates user properties.
    private const char UserDataSeparator = ',';

    // Separates users in the list.
    private const char UsersSeparator = ';';

    public static string ConvertListToString(IEnumerable<User> usersList)
    {
        var stringBuilder = new StringBuilder();

        // Build the users string.
        foreach (User user in usersList)
        {
            stringBuilder.Append(user.Name);
            stringBuilder.Append(UserDataSeparator);
            stringBuilder.Append(user.Age);
            stringBuilder.Append(UsersSeparator);
        }

        // Remove trailing separator.
        stringBuilder.Remove(stringBuilder.Length - 1, 1);

        return stringBuilder.ToString();
    }

    public static List<User> ParseStringToList(string usersString)
    {
        // Check that passed argument is not null.
        if (usersString == null) throw new ArgumentNullException("usersString");

        var result = new List<User>();

        string[] userDatas = usersString.Split(UsersSeparator);

        foreach (string[] userData in userDatas.Select(x => x.Split(UserDataSeparator)))
        {
            // Check that user data contains enough arguments.
            if (userData.Length < 2) throw new ArgumentException("Users string contains invalid data.");

            string name = userData[0];
            int age;

            // Try parsing age.
            if (!int.TryParse(userData[1], out age))
            {
                throw new ArgumentException("Users string contains invalid data.");
            }

            // Add to result list.
            result.Add(new User { Name = name, Age = age });
        }

        return result;
    }
}

You will win performance wise using the StringBuilder to build up your users string. You could also easily expand the converter to take account different separators/additional logic etc.

If you need a more generic solution (to be able to use for any class), you could create a converter which uses reflection to iterate over all the public fields, get/set properties to see what can be extracted as string and later reverse the process to convert your string back to the list.

Upvotes: 3

It&#39;sNotALie.
It&#39;sNotALie.

Reputation: 22814

I think what you're looking for is something that lets you dump all users to a string and get the users back from the string, correct?

I suggest something like this: Add a method that returns an XElement to the Users type:

public XElement GetXElement()
{
    return new XElement("User", new XElement("Name", this.FirstName)) //and so on...
}

and then one that decodes the string into a user:

static User GetUserFromXElement(string xml)
{
    XElement temp = XElement.Parse(xml);
    User temp = new User();
    foreach (XElement inner in temp.Elements())
    {
        switch inner.Name
        {
            case "Name":
                temp.Name = inner.Value
                break;
            //whatever
        }
    }
}

And then do this:

public string UsersToElements (List<Users> toWrite)
{
    Stringbuilder sb = new StringBuilder();
    StringWriter sw = new StringWriter(sb);
    XElement root = new XElement("root");
    XDocument temp = new XDocument(root);
    foreach (User user in toWrite)
    {
        root.Append(user.GetXElement());
    }
    temp.Save(sw);
    return sw.ToString();
}

and this:

public List<Users> ElementsToUsers (string xml)
{
    List<Users> usrsList = new List<Users>();
    XDocument temp = XDocument.Load(xml);
    foreach (XElement e in XDocument.Root.Elements())
    {
        usrsList.Append(Users.GetUserFromXElement(e));
    }
    return usrsList;
}

JSON solution (using JSON.NET)

public JObject GetJObject()
{
return new JObject("user", new JProperty("name", this.FirstName)); //so on
}

static User GetUserFromJObject(string json)
{
JObject obj = JObject.Parse(json);
return new User() { FirstName = (string)obj["user"]["name"] }; //so on
}

public string UsersToElements (List<Users> users)
{    
   JObject root = new JObject(from usr in users select new JAttribute("user", usr.GetJObject());
   return root.ToString();
}

public List<users> ElementsToUsers(string json)
{
List<Users> users = new List<Users>();
JObject temp = JObject.Parse(json);
foreach (JObject o in (JEnumerable<JObject>)temp.Children())
{
users.Add(Users.GetUserFromJObject(o.ToString());
}
return users;
}

I have no idea if ths works :/ (well the XML I know it does, not so sure about the JSON)

Upvotes: 1

user1968030
user1968030

Reputation:

Use this code

string combindedString = string.Join( ",", myList );

var Array = combindedString.Split( new [] {','} );

Upvotes: 0

Phil
Phil

Reputation: 43021

Use the string.Join method, e.g.

var joined = string.Join(",", users.Select(u => u.Name));

This would give you a single string of user's names separated by ','.

Or for multiple columns:

var joined = string.Join(",", 
                 users.Select(u => u.FirstName + " " + u.LastName ));

You can reverse the process using string.Split, e.g.

var split = joined.Split( new [] {','} );

Upvotes: 8

Related Questions