Can someone provide me an example of how maybe I store different functions in a dictionary with int as a key and function as value. So then I could easly call function as following:
functionsDictionary[123](string);
Note all functions in dictionary will take only one input which is string. And will have no return.
It sounds like you're after
Dictionary<int, Action<string>>
or possibly (based on your title)
Dictionary<uint, Action<string>>
Sample:
using System;
using System.Collections.Generic;
class Test
{
static void Main()
{
var dictionary = new Dictionary<int, Action<string>>
{
{ 5, x => Console.WriteLine("Action for 5: {0}", x) },
{ 13, x => Console.WriteLine("Unlucky for some: {0}", x) }
};
dictionary[5]("Woot");
dictionary[13]("Not really");
// You can add later easily too
dictionary.Add(10, x => Console.WriteLine("Ten {0}", x));
dictionary[15] = x => Console.WriteLine("Fifteen {0}", x);
// Method group conversions work too
dictionary.Add(0, MethodTakingString);
}
static void MethodTakingString(string x)
{
}
}
Dictionary<int, Action<string>> _functions = new Dictionary<int, Action<string>>();
_functions[123]("hello");
Related
Declaring a list of objects:
List<object> result = new List<object>();
and a list of int to store the ids:
List<int> ids = new List<int>();
I want to store in result objects containing the pair (string, list of int).
It works fine for the pair (string, int) but I want that when there are 2 identical strings to have only one object and the int values to be stored in a list.
ex: {pars = "xxx", id = 1} , {pars = "xxx", id = 2} becomes {pars = "xxx", id = (1,2 )}
For doing the initial functionality, I use a foreach through an object from which I take the string(pars) and the id:
foreach (dataBinding in myData)
{
var x = string.Join(" ", dataBinding.Params.Select(p => p.myDescription));
result.Add(new { pars = x, id = dataBinding.Id });
}
there could be more strings in Params, that's why I use the join.
As it is here it works by creating objects having the form (string, int). But my aim is to make it (string, list of int) and if there are two objects with same string to combine them as I wrote before.
I tried to add ids list as the second property of the object but probably I'm not doing it correctly.
result.Add(new { pars = x, ids = dataBinding.Id });
You can use LINQ, especially GroupBy:
Dictionary<string, List<int>> descriptionIDs = myData
.GroupBy(x => x.myDescription)
.ToDictionary(g => g.Key, g => g.Select(x => x.Id).ToList());
Now you have even a dictionary, not just a strange List<object> that contains anonymous types.
As someone mentioned, you can also use ToLookup which i'd also prefer:
var descriptionLookup = myData.ToLookup(x => x.myDescription);
Now you can get the ID-List easily:
var result = descriptionLookup.Select(g => new { pars = g.Key, ids = g.Select(x=> x.Id).ToList() }).ToList():
Perhaps I am not understanding the scenario fully but I suspect using the following would server your purpose.
List<Dictionary<string, List<int>>>
When the key doesn't exist you add it and when it does you just add to the List.
Below program depicts the current generic collection type, also allow to add a new value if Key Already exists.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
MyProgram p = new MyProgram();
p.Add("First" , 5);
p.Add("Second" , 8);
p.Add("Third" , 9);
p.Add("First" , 6);
p.Add("First" , 7);
p.PrintDictionary();
}
}
public class MyProgram
{
private Dictionary<string, List<int>> dict = new Dictionary<string, List<int>>();
public void Add(string key, int value)
{
if (dict.ContainsKey(key))
{
dict[key].Add(value);
}
else
{
dict.Add(key, new List<int>() {value});
}
}
public void PrintDictionary()
{
foreach(var keyValue in dict)
{
Console.WriteLine("Key : " + keyValue.Key);
foreach(var val in keyValue.Value)
{
Console.WriteLine(string.Format("\t Value : {0}", val));
}
}
}
}
Output :
Key : First
Value : 5
Value : 6
Value : 7
Key : Second
Value : 8
Key : Third
Value : 9
Check this Live Fiddle.
I have a method which takes a Dictionary<int, int> as a parameter
public void CoolStuff(Dictionary<int, int> job)
I want to call that method with one dictionary entry, such as
int a = 5;
int b = 6;
var param = new Dictionary<int, int>();
param.Add(a, b);
CoolStuff(param);
How can I do it in one line?
This is it, if you do not need the a and b variables:
var param = new Dictionary<int, int> { { 5, 6 } };
or even
CoolStuff(new Dictionary<int, int> { { 5, 6 } });
Please, read How to: Initialize a Dictionary with a Collection Initializer (C# Programming Guide)
var param = new Dictionary<int, int>() { { 5, 6 } };
I would like to be able to store various static methods in a List and later look them up and dynamically call them.
Each of the static methods has different numbers of args, types and return values
static int X(int,int)....
static string Y(int,int,string)
I'd like to have a List that I can add them all to:
List<dynamic> list
list.Add(X);
list.Add(Y);
and later:
dynamic result = list[0](1,2);
dynamic result2 = list[1](5,10,"hello")
How to do this in C# 4?
You can create a list of delegate-instances, using an appropriate delegate-type for each method.
var list = new List<dynamic>
{
new Func<int, int, int> (X),
new Func<int, int, string, string> (Y)
};
dynamic result = list[0](1, 2); // like X(1, 2)
dynamic result2 = list[1](5, 10, "hello") // like Y(5, 10, "hello")
You actually don't need the power of dynamic here, you can do with simple List<object>:
class Program
{
static int f(int x) { return x + 1; }
static void g(int x, int y) { Console.WriteLine("hallo"); }
static void Main(string[] args)
{
List<object> l = new List<object>();
l.Add((Func<int, int>)f);
l.Add((Action<int, int>)g);
int r = ((Func<int, int>)l[0])(5);
((Action<int, int>)l[1])(0, 0);
}
}
(well, you need a cast, but you need to somehow know the signature of each of the stored methods anyway)
List<dynamic> list = new List<dynamic>();
Action<int, int> myFunc = (int x, int y) => Console.WriteLine("{0}, {1}", x, y);
Action<int, int> myFunc2 = (int x, int y) => Console.WriteLine("{0}, {1}", x, y);
list.Add(myFunc);
list.Add(myFunc2);
(list[0])(5, 6);
I have a list like
List<string> TempList = new List<string> { "[66,X,X]", "[67,X,2]", "[x,x,x]" };
I need to add data to the dictionary from the above list
Dictionary<int, int> Dict = new Dictionary<int, int>();
so the Dict should contain
Key --> 66 value --> 67
i need to take 66(first value) from first string([66,X,X]) and 67(first value) from second string( [67,X,X]) and add it as a key value pair into the dictionary.
Now i'm following string replacing and looping methodology to do this .
Is there any way to do this in LINQ or Regular expression.
After your comment that you're starting from a list of lists, I understood what you were after. I'm reusing Jaroslav's 'GetNumber' function here. Wrote my sample with array of array of string, but should work just the same. The code below will throw if you have duplicate keys, which I presume is what you want if you're using a dictionary.
var input = new []
{
new [] { "[66,X,X]", "[67,X,2]", "[x,x,x]" },
new [] { "[5,X,X]", "[8,X,2]", "[x,x,x]" }
};
var query = from l in input
select new
{
Key = GetNumber(l.ElementAt(0)),
Value = GetNumber(l.ElementAt(1))
};
var dictionary = query.ToDictionary(x => x.Key, x => x.Value);
Here is an example using both string.Split() and a Regex:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<string> data = new List<string>() { "[66,X,X]", "[67,X,2]", "[x,x,x]" };
addToDict(data);
Console.ReadKey();
}
private static void addToDict(List<string> items)
{
string key = items[0].Split('[', ',')[1];
string val = items[1].Split('[', ',')[1];
string pattern = #"(?:^\[)(\d+)";
Match m = Regex.Match(items[0], pattern);
key = m.Groups[1].Value;
m = Regex.Match(items[1], pattern);
val = m.Groups[1].Value;
_dict.Add(key, val);
}
static Dictionary<string, string> _dict = new Dictionary<string, string>();
}
}
i suspect that your example is quite contrived though, so there may be a better solution especially if you need to process large numbers of strings into key/value pairs (i deliberately hardcoded index values because your example was quite simple and i didn't want to over complicate the answer). If the input data is consistent in format then you can make assumptions like using fixed indexes, but if there is a possibility of some variance then there may need to be more code to check the validity of it.
You can use a regular expression to extract the value from each item in the list, and if you want, use LINQ to select out two lists and zip them together (in C# 4.0):
var regex = new Regex(#"\d+");
var allValues = TempList.Select(x =>int.Parse(regex.Match(x).Value));
var dictKeys = allValues.Where((x,index)=> index % 2 == 0); //even-numbered
var dictValues = allValues.Where((x,index)=> index % 2 > 0); //odd numbered
var dict = dictKeys.Zip(dictValues, (key,value) => new{key,value})
.ToDictionary(x=>x.key,x=>x.value);
If you're using C# 3.5, you can use Eric Lippert's implementation of Zip().
IF I understand correctly: you want to create linked nodes like 66 -> 67, 67 -> 68, ... n -> n+1?
I would not use LINQ:
private static int GetNumber(string s)
{
int endPos = s.IndexOf(',');
return Int32.Parse(s.Substring(1, endPos-1));
}
And in code:
int first, second;
for (int i = 1; i < TempList.Count; i++)
{
first = GetNumber(TempList[i - 1]);
second = GetNumber(TempList[i]);
Dict.Add(first, second);
}
You should also perform checking, etc.
The sample assumes a list with at least 2 items.
List<List<string>> source = GetSource();
Dictionary<int, int> result = source.ToDictionary(
tempList => GetNumber(tempList[0]),
tempList => GetNumber(tempList[1])
);
I'm trying to find a LINQ oneliner that takes a Dictionary<String,Int> and returns a Dictionary<String,SomeEnum>....it might not be possible, but would be nice.
Any suggestions?
EDIT: ToDictionary() is the obvious choice, but have any of you actually tried it? On a Dictionary it doesn't work the same as on a Enumerable... You can't pass it the key and value.
EDIT #2: Doh, I had a typo above this line screwing up the compiler. All is well.
It works straight forward with a simple cast.
Dictionary<String, Int32> input = new Dictionary<String, Int32>();
// Transform input Dictionary to output Dictionary
Dictionary<String, SomeEnum> output =
input.ToDictionary(item => item.Key, item => (SomeEnum)item.Value);
I used this test and it does not fail.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
namespace DictionaryEnumConverter
{
enum SomeEnum { x, y, z = 4 };
class Program
{
static void Main(string[] args)
{
Dictionary<String, Int32> input =
new Dictionary<String, Int32>();
input.Add("a", 0);
input.Add("b", 1);
input.Add("c", 4);
Dictionary<String, SomeEnum> output = input.ToDictionary(
pair => pair.Key, pair => (SomeEnum)pair.Value);
Debug.Assert(output["a"] == SomeEnum.x);
Debug.Assert(output["b"] == SomeEnum.y);
Debug.Assert(output["c"] == SomeEnum.z);
}
}
}
var result = dict.ToDictionary(kvp => kvp.Key,
kvp => (SomeEnum)Enum.ToObject(typeof(SomeEnum), kvp.Value));
var collectionNames = new Dictionary<Int32,String>();
Array.ForEach(Enum.GetNames(typeof(YOUR_TYPE)), name =>
{
Int32 val = (Int32)Enum.Parse(typeof(YOUR_TYPE), name, true);
collectionNames[val] = name;
});