I have the following code:
var tuple = new Tuple<string, string>("MyKey", "MyValue");
var list = new List<string>();
var str = tuple.ToString();
list.Add(str);
// str has the value "(MyKey, MyValue)"
I have a predefined object where I need to use a list of strings.
I decided to use a Tuple but I am not sure how I can cast the str value back to a Tuple.
How can I store a key value in a List so that I can use lambda to query it e.g. by the key?
All this code:
var tuple = new Tuple<string, string>("MyKey", "MyValue");
var list = new List<string>();
var str = tuple.ToString();
list.Add(str);
// str has the value "(MyKey, MyValue)"
Could be replaced by a dictionary:
Dictionary<string, string> values = new Dictionary<string, string>();
values.Add("MyKey", "MyValue");
Then you can use linq to query the dictionary if you'd like to do so:
value = values.Where(x => x.ContainsKey("MyKey"));
You can get a list with all the keys as follows:
List<string> keys = values.Keys;
So no need to have a separate list for that.
If you want a list of string with two values separated by a coma, the dictionary will do too:
List<string> keysValues = (from item in values
select item.Key + "," + item.Value).ToList();
Use Dictionary.
var dictionary = new Dictionary<string, string>();
dictionary.Add("myKey", "myVal");
if (dictionary.ContainsKey("myKey"))
dictionary["myKey"] = "myVal1";
I suggest you use a Dictionary. But if you really need to do it this way:
To transform from the string back to Tuple (assuming that the Key itself will never contain a commma+space):
var tuple = Tuple.Create("MyKey", "MyValue");
var list = new List<string>();
var str = tuple.ToString();
list.Add(str);
// str has the value "(MyKey, MyValue)"
Console.WriteLine(str);
int comma = str.IndexOf(", ");
string key = str.Substring(1,comma-1);
string valuee = str.Substring(comma+2,str.Length-key.Length-4);
var tuple2 = Tuple.Create(key, valuee);
// 'tuple2' is now equal to the orignal 'tuple'
Related
I want to create a single object (possibly Dictionary) with string keys that will have different variable types as the value (string, int, bool, Dictionary<string,string> etc). Is this possible?
*I understand this might just be a fundamental difference of two languages AKA square peg round hole
You can use dynamic as values type, that match better than object to the question and you need no future castings:
var dictionary = new Dictionary<string, dynamic>();
dictionary.Add("1", 10);
dictionary.Add("2", "test");
dictionary.Add("3", true);
foreach ( var item in dictionary )
Console.WriteLine($"{item.Key} is type: {item.Value.GetType().Name} = {item.Value}");
Console.WriteLine();
int v = dictionary["1"] + 10;
Console.WriteLine(v);
string s = dictionary["2"] + " one";
Console.WriteLine(s);
bool b = !dictionary["3"];
Console.WriteLine(b);
Output
1 is type: Int32 = 10
2 is type: String = test
3 is type: Boolean = True
20
test one
False
https://learn.microsoft.com/dotnet/csharp/programming-guide/types/using-type-dynamic
A Dictionary<string, object> is roughly equivalent to an object in JavaScript.
Example:
var dictionary = new Dictionary<string, object>
{
"myString" = "helloWorld",
"myChild" = new Dictionary<string, object>
{
"myName" = "bobby tables"
}
};
var myString = (string)dictionary["myString"];
var myName = (string)((Dictionary<string, object>)dictionary["myChild"])["myName"];
You can also use the dynamic keyword and ExpandoObject.
dynamic obj = new ExpandoObject();
obj.MyString = "helloWorld";
obj.MyChild = new ExpandoObject();
obj.MyChild.MyName = "bobby tables";
string myString = obj.MyString;
string myName = obj.MyChild.MyName;
Is it possible to add a variable to a list name when using it?
Something like this:
string id = "1"; //Could be 2
List<string> List1 = new List<string> {"1","11" };
List<string> List2 = new List<string> {"2","22" };
foreach (var element in List+id)
{ //code here }
IDs could be a dozen different values, so I didn't even try with regular if(). Would that be the only way?
Use a dictionary:
var dict = new Dictionary<string, List<string>>();
dict.Add("1", new List<string> {"1","11" });
dict.Add("2", new List<string> {"2","22" });
Then you can do
foreach (var element in dict[id])
{
}
I have JSON string, something like:
{"1":{"1":"driver","2":"New York, NY"},"2":{"3":"male","2":"Alabama"}}
I have two enums:
public enum StoragePrimaryKeys
{
Login = 1,
Account = 2
};
public enum StorageSecondaryKeys
{
JobTitle = 1,
JobId = 2,
JobLocation = 3,
RenewDate = 4,
ExpirationDate = 5
};
How can I deserialize this JSON to an object?
I thought to do the next thing:
var jss = new JavaScriptSerializer();
Dictionary<string, string> sData = jss.Deserialize<Dictionary<string, string>>(value);
string output = string.empty;
foreach (KeyValuePair<string, string> entry in sData)
{
if (Convert.ToInt32(entry.Key) == StorageSecondaryKeys.JobTitle) {
}
output += "\n key:" + entry.Key + ", value:" + entry.Value;
}
But maybe there is more efficient way?
I think It's a new question cause I have numbers in the keys that should be translated to the strings of the enums
Thanks.
It appears your data model should be as follows:
Dictionary<StoragePrimaryKeys, Dictionary<StorageSecondaryKeys, string>>
However, from experimentation, I found that JavaScriptSerializer does not support enums as dictionary keys, so you cannot deserialize to such an object directly. Thus you could deserialize to string-keyed dictionaries and convert using Linq:
var dict = new JavaScriptSerializer().Deserialize<Dictionary<string, Dictionary<string, string>>>(value)
.ToDictionary(
p => (StoragePrimaryKeys)Enum.Parse(typeof(StoragePrimaryKeys), p.Key),
p => p.Value.ToDictionary(p2 => (StorageSecondaryKeys)Enum.Parse(typeof(StorageSecondaryKeys), p2.Key), p2 => p2.Value));
This will produce the dictionary you want.
Alternatively, you could install json.net and deserialize directly to the desired dictionary, since Json.NET does support enum-keyed dictionaries:
var dict = JsonConvert.DeserializeObject<Dictionary<StoragePrimaryKeys, Dictionary<StorageSecondaryKeys, string>>>(value);
I am trying to customise a DevExpress grid filter.
Currently I return the data from my api, and so I need to parse the built in string which is returned from the grid.
An example of the filter string is;
StartsWith([name], 'test') And StartsWith([quantity], '12') And
StartsWith([id], '1') And StartsWith([date], '01/10/2015')
I would like to convert this to a Dictionary in the most efficient way?
You could use Regex for filtering the key/value pair outta your string and a simple foreach to prepare the dictionary.
This could be a solution:
public static Dictionary<string, object> FilterAPIData(string data)
{
var r = new Regex(#"\[\w+\], \'[\w/]+\'");
var result = r.Matches(data);
var dict = new Dictionary<string, object>();
foreach (Match item in result)
{
var val = item.Value.Split(',');
dict.Add(val[0], val[1]);
}
return dict;
}
Regex might be the best option for this, but I'll show you how to do it without Regex as it can be a bit difficult to understand.
Assuming your string will always be in this format you can do this:
string str = "StartsWith([name], 'test') And StartsWith([quantity], '12') And StartsWith([id], '1') And StartsWith([date], '01/10/2015')";
var strArray = str.Split(new string[]{"And "}, StringSplitOptions.None);
var dict = new Dictionary<string, string>();
foreach(var value in strArray)
{
dict.Add(GetStringBetween(value, "[", "]"), GetStringBetween(value, "'", "'"));
}
private string GetStringBetween(string value, string startDelim, string endDelim)
{
int first = value.IndexOf(startDelim) + startDelim.Length;
int last = value.LastIndexOf(endDelim);
return value.Substring(first, last - first);
}
//Output :
//name test
//quantity 12
//id 1
// date 01/10/2015
If there other formats the string can be in you can adjust as needed. I would also consider adding in more validation/error handling, but I will let you figure that out ;)
I am curious if there is a way where I can capture the lower lines (the creation of the dictionary and loop to add values) in the linq statement itself. Right now the select new returns a new anonymous type but I am wondering if there is a way to make it return a Dictionary with all the values pre-populated.
XDocument reader = XDocument.Load("sl.config");
var configValues = from s in reader.Descendants("add") select new { Key = s.Attribute("key").Value, s.Attribute("value").Value };
Dictionary<string, string> Settings = new Dictionary<string, string>();
foreach (var s in configValues)
{
Settings.Add(s.Key, s.Value);
}
Try Enumerable.ToDictionary extension method.
XDocument reader = XDocument.Load("sl.config");
var Settings = reader.Descendants("add")
.ToDictionary(s => s.Attribute("key").Value, s => s.Attribute("value").Value);
var = XDocument.Load("sl.config").Descendants("add").ToDictionary
(x => x.Attribute("key"). Value, x => x.Attribute("value"). Value);