I am using a Library with a class that have the following constructors:
public JobDataMap(IDictionary<string, object> map);
public JobDataMap(IDictionary map);
I created an instance of JobDataMap:
var jdm = new JobDataMap(new Dictionary<String, Object> {
{ "Manager", myObject }
});
But I am getting the compilation error:
The call is ambiguous between the following methods or properties:
'JobDataMap.JobDataMap(IDictionary<string, object>)' and 'JobDataMap.JobDataMap(IDictionary)'
How to solve this?
You can enforce the type being passed like so:
var jdm = new JobDataMap((IDictionary<string, object>)new Dictionary<String, Object> {
{ "Manager", myObject }
});
Or you could make a factory method and make the non-generic constructor (I'm assuming you use this less) private:
public class JobDataMap
{
public JobDataMap(IDictionary<string, object> map)
{
}
private JobDataMap(IDictionary map)
{
}
public static JobDataMap FromNonGenericMap(IDictionary map)
{
return new JobDataMap(map);
}
}
Usage:
var jdm = JobDataMap.FromNonGenericMap(someNonGenericDictionary);
and then you can use the regular generic one like so:
var jdm = new JobDataMap(new Dictionary<String, Object> {
{ "Manager", myObject }
});
You can cast it to the type for the constructor you want it to use:
var jdm = new JobDataMap((IDictionary<string, object>) new Dictionary<String, Object> {
{ "Manager", new object() }
});
This design does seem a bit dubious, however...
I got stuck to change the following array to a dictionary.
public static string[][,] patterns = new string[][,]
{
new string[,] {
{ "1,2,3" },
{ "3,2,5" },
},
new string[,] {
{ "4,4,3" },
{ "7,1,2" },
},
};
This is what I have:
public Dictionary<string, string[]> patterns = new Dictionary<string, string[]>();
I can't fill the array with predefined values.
I want to change to a dictionary, because it has a key.
Can I also change the above array to a key and values format?
I want something like this: { "keyNameExample1", "1,2,3", "4,5,6", "etc"}. I want do something like this: patterns["keyNameExample", 1 (integer array pack)]; or patterns["keyNameExample", 2]; (to get the second arrays)
{ "keyNameExample1", "1,2,3", "4,5,6", "etc"} { "keyNameExample2", "5,7,8", "1,1,1", "etc"} and get it like this: patterns["keyNameExample1", 2]; or patterns["keyNameExample2", 1];
can make it even shorter like:
public static Dictionary<string, string[]> demo = new Dictionary<string, string[]>
{
{ "abc", new[]{"1","2"}},
{ "def", new[]{"3","4"}},
};
and with C# 9 you can even do:
public static Dictionary<string, string[]> demo = new()
{
{ "abc", new[]{"1","2"}},
{ "def", new[]{"3","4"}},
};
You can just make it a dictionary with a list, and I guess that covers your requirements (index access, variable number of integers for the index element). Here is an example (for the value list I am not sure, whether you really want a string or ints, in case just change the type):
// define dictionary
IDictionary<string, IList<int>> dict = new Dictionary<string, IList<int>>();
// assign values
dict["abc"] = new List<int> { 2, 4, 8 };
dict["def"] = new List<int> { 10, 12, 14 };
// get value
int dictDef2 = dict["def"][1];
Finally, I got it.
public static Dictionary<string, string[]> demo = new Dictionary<string, string[]>
{
{ "abc",
new string[]
{
"1",
"2"
}
},
{ "def",
new string[]
{
"3",
"4"
}
},
};
Contains check:
if (demo.ContainsKey("abc"))
{
}
Get the value(s):
demo["abc"][0]
Thanks for any help.
If you want to change existing array, you can try Linq:
using System.Linq;
...
public static string[][,] patterns = new string[][,] {...}
...
public Dictionary<string, string[]> patternsDict = patterns
.Select((value, index) => (
key : $"keyNameExample{index}",
value : value.OfType<string>().ToArray()))
.ToDictionary(pair => pair.key, pair => pair.value);
Note, that we have to convert (flatten) 2d array into ordinal one
If you want just to declare dictionary and fill it:
public Dictionary<string, string[]> patterns = new Dictionary<string, string[]>() {
{"keyExample1", new string[] { "1,2,3", "3,2,5" }},
{"keyExample1", new string[] { "4,4,3", "7,1,2" }},
};
public string[][,] patterns = new string[][,] { new string[,] { { "1,2,3" }, { "3,2,5" } }, new string[,] { { "4,4,3" }, { "7,1,2" } } };
Dictionary<string, string[,]> patternsDictionary = new Dictionary<string, string[,]>();
for (int i = 0; i < patterns.Length; i++)
{
patternsDictionary.Add(i.ToString(), patterns[i]);
}
Console.WriteLine(patternsDictionary["0"][0,1]); // Returns 2 - from { "1,2,3" }
I have seen people use yield return, although every time I try and use it in foreach it tells me something along the lines of: The body of CollectDictionary cannot be an iterator block because Dictionary<string, object> is not an interator interface type
I have a lot of methods line the following, is there a way to reduce boilerplate?
public Dictionary<string, object> CollectDictionary()
{
var configLines = File.ReadAllLines(_file).Where(IsValidConfigLine);
var configElements = new Dictionary<string, object>();
foreach (var configElement in configLines)
{
configElements.Add(configElement.Split("=")[0], configElement.Split("=")[1]);
}
return configElements;
}
You can reduce the amount of code by using .ToDictionary().
public Dictionary<string, object> CollectDictionary()
{
string[] configLines = new string[]
{
"foo1=bar1",
"foo2=bar2",
"foo3=bar3",
"foo4=bar4",
};
return configLines.Select(configElement => configElement.Split("="))
.ToDictionary(splt => splt[0], splt => (object)splt[1]);
}
This should return the following Dciotnary
{
{ "foo1", "bar1" },
{ "foo2", "bar2" },
{ "foo3", "bar3" },
{ "foo4", "bar4" }
}
I would like to simplify below nested foreach loops using LINQ but couldn't figure out the way. I guess I can use SelectMany using lambda but not sure. I want to create list of objects of ClassA after this nested iteration. Any help is appreciated:
public List<ClassA> GetLists(Dictionary<string, Dictionary<IEnumerable, Dictionary<string, ClassB>>> groups)
{
var retOutput = new List<ClassA>();
foreach (KeyValuePair<string, Dictionary<IEnumerable, Dictionary<string, ClassB>>> group1 in groups)
{
foreach (KeyValuePair<IEnumerable, Dictionary<string, ClassB>> group2 in group1.Value)
{
foreach (KeyValuePair<string, ClassB> group3 in group2.Value)
{
GetList(retOutput, group1.Key,
group2.Key,
group3);
}
}
}
return retOutput;
}
private static void GetList(List<ClassA> retOutput,
string group1Key,
IEnumerable group2Key,
KeyValuePair<string, ClassB> group3)
{
List<List<string>> itemIdsLists = group3.Value.ItemId.IntoChunks(2000);
foreach (var itemIdList in itemIdsLists)
{
var currentRequest = new ClassA
{
TransactionType = group1Key,
Filters = new Dictionary<string, object>(),
ItemIds = new List<string>(),
PropStreamsDict = new Dictionary<string, Tuple<long, string>>()
};
if (group2Key is Dictionary<string, object>)
{
currentRequest.Filters = (Dictionary<string, object>)group2Key;
}
currentRequest.PropStreamsDict.Add(group3.Key, Tuple.Create(group3.Value.StreamId,
group3.Value.Uom));
currentRequest.ItemIds.AddRange(itemIdList);
retOutput.Add(currentRequest);
}
}
You should use SelectMany to make nested foreach.
Here what I come up with:
public List<ClassA> GetLists(Dictionary<string, Dictionary<IEnumerable, Dictionary<string, ClassB>>> groups)
{
return groups
.SelectMany(grp1 => grp1.Value
.SelectMany(grp2 => grp2.Value
.SelectMany(grp3 => grp3.Value.ItemId
.IntoChunks(2000)
.Select(itemIdList =>
new ClassA
{
TransactionType = grp1.Key,
Filters = grp2.Key is Dictionary<string, object> ?
(Dictionary<string, object>)grp2.Key :
new Dictionary<string, object>(),
ItemIds = new List<string>(itemIdList),
PropStreamsDict = new Dictionary<string, Tuple<long, string>>
{
{ grp3.Key, Tuple.Create(grp3.Value.StreamId, grp3.Value.Uom) }
}
}
)
)
)
)
.ToList();
}
You didn't post your ClassA and ClassB so I had to guess.
how can I convert IDictionary data into JSON using NewtonJSON. My IDictionary data contains the following data:
type: 19
id : 4433
Now I want to convert it into
{
"type":"19",
"id": "4433"
}
How do I do this?
IDictionary<string, string> messageData = message.Data;
var json = JsonConvert.SerializeObject(messageData, new JsonSerializerSettings()
{
Formatting = Formatting.Indented
});
here is the update please see my screenshots
Json.NET (formely Newtonsoft.Json) already has the built in capability to convert dictionaries into Json objects:
// the dictionary may be anything IDictionary<string, whatever>, Json.NET will convert it anyway
IDictionary<string, string> dict = new Dictionary<string, string>()
{
{ "type", "19" },
{ "id" ,"4433"}
};
var json = JsonConvert.SerializeObject(dict, new JsonSerializerSettings()
{
Formatting = Formatting.Indented
});
Outputs:
{
"type": "19",
"id": "4433"
}
Demo: https://dotnetfiddle.net/a562kK
[Edit]
The type you are trying to serialize is not an IDictionary at all. You should try to convert it to a dictionary first.
Here an example (assuming message.Data implements at least IEnumerable):
var dict = new Dictionary<string, string>();
foreach(var item in message.Data)
{
// get Key and Value from item here
var kvp = item as KeyValuePair<string, string>; // this is just an example, I do not know what type your message.Data is returning
dict.Add(kvp.Key, kvp.Value);
}
// now you may serialize `dict`
var list = d.Select(x => new obj{ type = x.Key, id = x.Value});
var json = JsonConvert.SerializeObject(list);
Class:
public class obj
{
public string type { get; set; }
public string id { get; set;}
}