Hey, how can i make an array out of a string which contains something like this:
name:Trainwreck,location:forum,xpos:12ypos:67
So that's my string, now i want to create an array out of this so that i can ask the value from that array by the name. So for example in my array i should be able to do this:
myArray.name; (should give me: Trainwreck)
myArray.xpos; (should give me: 12)
myArray.location; (should give me: forum)
etc.
So my question is, how can i convert a string like that to an array?
Shuja Ali
July 12th, 2009, 01:31 PM
Assuming that the string would always look like this, You will have to write a class with public string properties. Then in the constructor of the class, you will pass this string. The constructor will then break the string using String.Split method first using comma and then using colon and put the strings into respective properties.
memeloo
July 12th, 2009, 02:11 PM
to be precise it won't be an array but a class. you want to turn you string into a class instance and an array could be used to store those instances:
if you decide to use an array and not some typed collection like List etc.
Trainwreck
July 13th, 2009, 03:01 AM
OK i get the idea of splitting the string, but what i don't get is how to create the members of the class.
The format of the string is always the same, but the data in it can be different. So it's not always sending
name:Trainwreck,location:forum,xpos:12ypos:67
It could also be:
ID:12,rank:4,gear:none
So would it still be possible to construct a class, array or list (or what ever is best in this case) when i don't know the exact vars?? In PHP i could do something like this with a 2D array. Maybe this is possible in C# too??
//When the string is splitted
string s1 = myArray[0]["name"];
string s2 = myArray[0]["gear"];
string s3 = myArray[0]["location"];
etc.
BigEd781
July 13th, 2009, 03:31 AM
First, I would definitely try my best to normalize that data into one format if possible. Otherwise, your class(es) will need to know the format somehow.
class MyClass
{
public MyClass( string data )
{
// parse the string and assign fields
}
}
memeloo
July 13th, 2009, 03:32 AM
So would it still be possible to construct a class, array or list (or what ever is best in this case) when i don't know the exact vars?? In PHP i could do something like this with a 2D array. Maybe this is possible in C# too??
//When the string is splitted
string s1 = myArray[0]["name"];
string s2 = myArray[0]["gear"];
string s3 = myArray[0]["location"];
your property names are the ID, rank and gear and values respectively 12, 4 and "none" so constricting a class is very simple
Trainwreck
July 13th, 2009, 04:53 AM
Sorry, but im not sure how to create the class. Does this mean i have to define the member vars in that class, and fill them when splitting the string??
public MyClass ( string longString )
{
//split the string and place the values in the right member variables??
}
memeloo
July 13th, 2009, 04:55 AM
Sorry, but im not sure how to create the class.
I think you need something like this: http://www.csharp-station.com/Tutorials/Lesson07.aspx :D
Trainwreck
July 13th, 2009, 07:15 AM
lol, it's not that i don't know how to work with classes. It's more that i don't know how to create it when i don;t know what kind of member variables there are.
But i think i can do this with a dictionary list.
memeloo
July 13th, 2009, 07:17 AM
but you do know what their names are, you've shown us the names:
ID, rank, gear
monalin
July 13th, 2009, 10:42 AM
Sorry, but im not sure how to create the class. Does this mean i have to define the member vars in that class, and fill them when splitting the string??
public MyClass ( string longString )
{
//split the string and place the values in the right member variables??
}
What you need to do is use a dictionary object inside your class. For this example i'll assume that all the values are strings however you can use whatever data type you want. Assuming your data is always in the same format, " <name>: <value>, .... " this should work for you.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
public class MyClass
{
private Dictionary<String, String> _values = null;
public MyClass(String input)
{
ParseInput(input);
}
private void ParseInput(String input)
{
_values = new Dictionary<String, String>();
Regex reg = new Regex(@"(?<name>[^:]+):(?<value>[^,]+),?", RegexOptions.Singleline | RegexOptions.IgnoreCase);
Match m = reg.Match(input);
while(m.Success)
{
_values[m.Groups["name"].Value] = m.Groups["value"].Value;
m = m.NextMatch();
}
}
public String this[String name]
{
get
{
if (_values.ContainsKey(name))
return _values[name];
return String.Empty;
}
}
}
To use this class all you need to do is the following.
MyClass mc = new MyClass("name:Trainwreck,location:forum,xpos:12,ypos:67");
String name = mc["name"];
....
....
You can actually create a class on the fly if you don't know what properties you are going to have in the class are but this is defiantly a more advanced topic. Which brings on a whole other level of complexity to the scenario. This should work for you since it doesn't require you know the names of the properties at compilation.
rliq
July 15th, 2009, 12:21 AM
Neat answer and also reminded me of when I had a problem and decided to use Regular Expressions... I then had 2 problems ;)
rliq
July 15th, 2009, 12:34 AM
I prefer monolin's way, but here's another technique using a String Extender. This is by no means the neatest version!
Assumes .NET 3.x and above...
public static string GetValue(this string thisString, String name)
{
int index1 = thisString.IndexOf(name);
if (index1.Equals(-1))
return String.Empty;
index1 += name.Length + 1;
int index2 = thisString.IndexOf(',', index1);
if (index2.Equals(-1))
return thisString.Substring(index1);
String a = "name:Trainwreck,Trainwreck:forum,xpos:12,ypos:67";
String b = a.GetValue("Trainwreck");
// b = "forum"
rliq
July 15th, 2009, 02:16 AM
All being said, a String Extender is suppose to extend Strings, as in ALL Strings... Mine is for a special case for Strings that are in a certain format. So really, if this is a large project with many Extenders, I don't think it is the way to go.
rliq
July 15th, 2009, 06:39 PM
One more solution using a Class (but not a Dictionary)
public class KeyValueString
{
private String _keyValueString;
public KeyValueString(String keyValueString)
{
// if (keyValueString is no in the correct format)
// throw an exception
_keyValueString = keyValueString;
}
public KeyValueString(KeyValueString keyValueString)
{
_keyValueString = keyValueString.ToString();
}
public override String ToString()
{
return _keyValueString;
}
KeyValueString a = new KeyValueString("name:Trainwreck,Trainwreck:forum,xpos:12,ypos:67");
String b = a.GetValue("Trainwreck");
String c = a.GetValue("xpos");
I guess if you knew the C# types of the value, given a certain key (eg xpos = Int32), you could write other member functions GetInt32Value, GetDoubleValue etc.
Hope this helped.
monalin
July 16th, 2009, 09:16 AM
The main problem with your solution is that it needs to perform calculations each time the function gets run. I haven't tried it, but i assume it might work. However, you want to avoid these type of functions if possible. There's no reason to not parse the string into a list of name / value pairs i.e Dictionary or NameValueCollection.
BigEd781
July 16th, 2009, 11:57 AM
The main problem with your solution is that it needs to perform calculations each time the function gets run. I haven't tried it, but i assume it might work. However, you want to avoid these type of functions if possible. There's no reason to not parse the string into a list of name / value pairs i.e Dictionary or NameValueCollection.
Well, that is just the method to get the value. You can use it to create a dictionary.
memeloo
July 16th, 2009, 12:38 PM
and why not something like this?
class MyClass
{
private int id;
private string name;
private int rank;
public int Id
{
get { return id; }
}
public int Rank
{
get { return rank; }
}
public string Name
{
get { return name; }
}
public MyClass(string text)
{
// parse the text
}
}
monalin
July 16th, 2009, 01:02 PM
Well, that is just the method to get the value. You can use it to create a dictionary.
Would be counter productive to create a dictionary like this because he would need to know the all the values ahead of time. I suppose you could use the dictionary as a caching mechanism though and just save the result in a dictionary and only resort to the GetValue() if no entry is in the dictionary... Something like this.
In the original problem it was stated that the fields present in the string would be different depending on what he was trying to do. So we needed a solution that was a little more generic and worked with any string of name/value pairs.
memeloo
July 16th, 2009, 01:48 PM
In the original problem it was stated that the fields present in the string would be different depending on what he was trying to do. So we needed a solution that was a little more generic and worked with any string of name/value pairs.
oh, sorry, I must have overseen it... anyway it would be cool if it was possible to create classes/structures dynamicaly, at least their properties
monalin
July 16th, 2009, 01:55 PM
oh, sorry, I must have overseen it... anyway it would be cool if it was possible to create classes/structures dynamicaly, at least their properties
It is possible to create a class/structure using some of the more advanced features of C#. But that's very overkill for this problem hah. All the required tools are in the .NET framework to create a new class and add properties etc... I'm trying to think of a reason why I would want to do that though.
memeloo
July 16th, 2009, 02:02 PM
It is possible to create a class/structure using some of the more advanced features of C#.
could you point me to this features, I'd like to experiment :D
I'm trying to think of a reason why I would want to do that though.
maybe not this time but it's good to know there is such possibility just in case :p
monalin
July 16th, 2009, 02:22 PM
could you point me to this features, I'd like to experiment :D
I don't have time to write up a good example but i was able to find a link that explains how its done. Defiantly an interesting concept but like the author says, its slow performance wise. I'm sure you can understand why it would be.
The main problem with your solution is that it needs to perform calculations each time the function gets run. I haven't tried it, but i assume it might work. However, you want to avoid these type of functions if possible. There's no reason to not parse the string into a list of name / value pairs i.e Dictionary or NameValueCollection.
Agreed, I just posted it as an alternative way. I guess, it would depend on how many times a given KeyValueString was going to be accessed before being discarded. Many times, then a Dictionary would be quicker, a couple, then maybe a parsed string.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.