adding values from an object to a dictionary - c#

I have an object that I obtained from an xml file and it contains a field of SeriesCode and ProductCodes associated with the specified Series code.
i.e.
SeriesCodeA
prodCode1
prodCode2
prodCode3
SeriesCodeA
prodCode4
prodCode5
prodCode6
I created a the following dictionary
Dictionary<string, List<string>> dictSeries = new Dictionary<string, List<string>>();
The values from the object I want to add to the dictionary. So in other words I want to, for each series code added to the Dictionary key as a string value add the corresponding product codes as string values.
something like
foreach (var s in series)
{
string code = s.SeriesCode;
if (dictSeries.ContainsKey(code))
{
foreach (var l in s.ProductCodes)
{
dictSeries[code].Add(l);
}
}
}
The above is not quite right
How can I add the SeriesCodes as keys to the dictionary with the corresponding product codes as string values(List)?

Use LINQ and ToDictionary method to make it more readable:
var dictSeries = series.ToDictionary(x => x.SeriesCode, x => x.ProductCodes);
A assumed your Series class looks like that:
class Serie
{
public string SeriesCode { get; set; }
public List<string> ProductCodes { get; set; }
}
Your code also will work, but needs few improvements:
foreach (var s in series)
{
string code = s.SeriesCode;
if (!dictSeries.ContainsKey(code))
{
dictSeries.Add(code, new List<string>());
}
foreach (var l in s.ProductCodes)
{
dictSeries[code].Add(l);
}
}

Related

Is there a more efficient way to loop through multiple lists

I have 4 lists of strings - These are all identical in length
var nameList;
var dateList;
var versionList;
var downloadList;
I'm currently looping through each list individually and then adding the contents of each list into a concurrent queue
var concurrentNameQueue= new ConcurrentQueue<string>();
var concurrentDateQueue= new ConcurrentQueue<string>();
var concurrentVersionQueue= new ConcurrentQueue<string>();
var concurrentDownloadQueue= new ConcurrentQueue<string>();
foreach (var name in nameList)
{
concurrentNameQueue.Enqeue(name);
}
foreach (var date in dateList)
{
concurrentDateQueue.Enqeue(date);
}
foreach (var version in versionList)
{
concurrentVersionQueue.Enqeue(version);
}
foreach (var download in downloadList)
{
concurrentDownloadQueue.Enqeue(download);
}
This process seems awfully repetitive and got me wondering if there is a more efficient way to loop through all these lists
Is there a more efficent way to do this?
You can write an extension method and then call it:
public static void Enqueue<T>(this ConcurrentQueue<T> queue, IEnumerable<T> items)
{
foreach (var item in items)
queue.Enqueue(item);
}
concurrentNameQueue.Enqueue(nameList);
concurrentDateQueue.Enqueue(dateList);
concurrentVersionQueue.Enqueue(versionList);
concurrentDownloadQueue.Enqueue(downloadList);
Or as you are initializing the list just above then use the second
constructor that requires an IEnumerable<T> as input:
var concurrentNameQueue = new ConcurrentQueue<string>(nameList);
var concurrentDateQueue = new ConcurrentQueue<string>(dateList);
var concurrentVersionQueue = new ConcurrentQueue<string>(versionList);
var concurrentDownloadQueue = new ConcurrentQueue<string>(downloadList);
But as I mentioned in my comment it seems like you should create a single class with 4 properties, one for each of name, date, version and download. Then you have one list of that class instead of keeping 4 lists synced.
Instead of making multiple list, use data structure that has multiple properties
Thats the advantage of OOP. Create single list of this instead
public class DownloadItem
{
public string Name { get; set; }
public string Date { get; set; }
public string Version { get; set; }
public string Download { get; set; }
}

sending key-pair array object using ajax in c#

I am trying to send a key-pair based array object using ajax, here array is created dynamically
["{\"key\":\"#c1\",\"value\":\"g1\"}","{\"key\":\"#c1\",\"value\":\"g2\"}", "{\"key\":\"#c2\",\"value\":\"g3\"}", "{\"key\":\"#c4\",\"value\":\"g4\"}"]
Above is json formatted data which i am sending to a method and able to receive it. At c# end Dictionary<string, string> Columns is used. problem here is that the key values are just number and values contain each element of above mentioned json data as shown below,
foreach(var eachVals in columns)
{
string k = eachVals.Key;
string col = eachVals.Value;
}
when iterating the dictionary eachVals.key is array index (0,1,...) and eachVals.Value contains {"key":"#c1","value":"g1"}
So what i want is separate keys i.e "#c1","#c1","#c2"... and values i.e "g1","g2"...
You would need to deserialize the values from col. Using Newtonsoft.Json, would look something like this:
Dictionary<string, string> columns = new Dictionary<string, string>
{
{ #"0", #"{""key"": ""#c1"", ""value"":""g1"" }" },
{ #"1", #"{""key"": ""#c2"", ""value"":""g2"" }" }
};
var result = columns.ToDictionary(
column => JsonConvert.DeserializeObject<MyObj>(column.Value).key,
column => JsonConvert.DeserializeObject<MyObj>(column.Value).value);
Where MyObj is:
internal class MyObj
{
public string key { get; set; }
public string value { get; set; }
}
I think you can do or get the idea from this:
foreach(var eachVals in columns)
{
var e = eachVals.Value.Split(',');
e = e[0].Split(':');
string k = e[0];
string v = e[1];
}

Foreach Loop using KVP to iterate through a Multi-Dimensional List

I want to use a foreach k, v pairs loop to run through a multidimensional list, and output those values elsewhere. Here is the code:
public class LogTable
{
public string FunctionName { get; set; }
public string LogTime { get; set; }
}
public class TableVars
{
public List<LogTable> loggingTable { get; set; }
public TableVars()
{
loggingTable = new List<LogTable>();
}
public void createLogList()
{
loggingTable = new List<LogTable>();
}
}
foreach( KeyValuePair<string, string> kvp in tablevars.loggingTable)
{
// output would go here. I haven't looked it up yet but I assume it's something
// along the lines of var = k var2 = v? Please correct me if I'm wrong.
}
When I run my mouse over 'foreach' I get a warning saying - 'Cannot convert type 'DataObjects.LogTable' to 'System.Collections.Generic.KeyValuePair. How can I resolve this issue, or is there a more efficient way to accomplish the same goal?
Thanks!
I should have added more context, sorry. I'm trying to return the two different values inside the properties 'FunctionName' and 'LogTime' which I have added via:
var tablevars = new TableVars();
tablevars.loggingTable.Add(new LogTable { FunctionName = errorvalue, LogTime = logtime });
To specify more accurately, the intention of the foreach k, v loop was to grab every distinct property of FunctionName and LogTime and input them into a database in SQL Server. This is why the distinction between k, v (or FunctionName, LogTime) is important. Again, please correct me if I'm wrong.
You cannot use KeyValuePair<>, because you don't enumerate a Dictionary<>. But you don't need to, simply do this:
foreach(LogTable logTable in tablevars.loggingTable)
{
// do whatever with logTable.FunctionName and logTable.LogTime
}
Either change your foreach to iterate through List<LogTable>
foreach( LogTable lt in tablevars.loggingTable)
{...}
OR
Use a KeyValuePair instead of creating class LogTable
public class TableVars
{
public Dictionary<string,string> loggingTable { get; set; }
public TableVars()
{
loggingTable = new Dictionary<string,string>();
}
public void createLogList()
{
loggingTable = new Dictionary<string, string>();
}
}
foreach( KeyValuePair<string, string> kvp in tablevars.loggingTable)
{
//loggingTagle is now a KeyValuePair
}

Foreach in wpf (cannot convert char to string)?

Each time I add an item in the list ListData that I have created I have to check that does not exist.
This is the element:
public ObservableCollection<LabelGroup_RowItem> ListData = new
ObservableCollection<LabelGroup_RowItem>();
public class LabelGroup_RowItem
{
public int ID { get; set; }
public string Name { get; set; }
}
element.Name = TextEdit_GroupName.Text;
foreach (string x in ucLabel.ListData[0].Name)
{
if (x.Equals(element.Name))
{
MessageBox.Show("....");
}
}
How should I do?
While it's hard to know what ucLabel is, you probably meant:
foreach (var x in ucLabel.ListData)
{
if (x.Name.Equals(element.Name))
{
MessageBox.Show("....");
}
}
you can use Linq - this will match if any item in ListData(.Name) matches your text field
string TextToMatch = TextEdit_GroupName.Text;
if(ListData.Any(x => x.Name == TextToMatch))
{
MessageBox.Show(string.format("{0} already exists",TextToMatch);
}
bare in mind this is mostly psuedo, but it should work
about equals metchod
If Name property is unique try to compare it with simple '==' operator.
Also your foreach loop looks wierd. I am not sure if this: ucLabel.ListData[0].Name
is IEnumerable. Maybe you think about
foreach (var x in ucLabel.ListData){
if (x.Name==element.Name) { do something }
}
Also remember to avoid adding or removing ListData content in foreach loop becous it will crash your code.

How to elegantly parse the following text into a dictionary

I have the following text that I need to put into a dictionary. At first sight I thought that it would be very easy but at the end I found myself doing extensive string search and finding sometimes values that break the parser.
"0":
{
"key":"valueWithAnyCharInside",
"key2":"valueWithAnyCharInside",
"key3":"valueWithAnyCharInside"
},
This will map into the following model:
class Item
{
private int id;
private Dictionary<string, string> data;
}
Any ideas? Maybe using regex ...
Your data format is probably a JSON, but you gave only a part of it. I've modified it slightly as:
{"0":
{
"key":"valueWithAnyCharInside",
"key2":"valueWithAnyCharInside",
"key3":"valueWithAnyCharInside"
}
}
now you can parse it as following:
string json = ...; //your json goes here
var serializer = new JavaScriptSerializer();
var parsed = serializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(json);
//printing data
parsed["0"].Select(pair => string.Format( "{0} - {1}", pair.Key, pair.Value))
.ToList()
.ForEach(Console.WriteLine);
prints:
key - valueWithAnyCharInside
key2 - valueWithAnyCharInside
key3 - valueWithAnyCharInside
To get strongly typed List<Item> use next code
List<Item> items = parsed.Select(pair => new Item { Id = int.Parse(pair.Key),
Data = pair.Value})
.ToList();
Where Item is :
class Item
{
public int Id { get; set; }
public Dictionary<string, string> Data {get;set;}
}

Categories

Resources