How do i extract from a nested dictionary? - c#

I have created a nested dictionary with the following:
Dictionary<DateTime, Dictionary<string, string>> dateDict =
new Dictionary<DateTime, Dictionary<string, string>>();
I then enter values to this dictionary using the following:
while (reader.Read())
{
DateTime date = DateTime.Parse(reader["Event_Date"].ToString());
string name = reader["Event_Name"].ToString();
string guid = reader["Event_GUID"].ToString();
dateDict.Add(date, new Dictionary<string, string>());
dateDict[date].Add(name, guid);
}
My question is how do I correctly pull the variables back out from the nested dictionary?
I have this loop running to pull values out and assign them to DateTimePickers and TextFields:
for (int i = 0; i < dateDict.Count; i++)
{
DateTime keyVar = dateDict.ElementAt(i).Key;
eventDateBoxes[i].Value = keyVar;
eventTextBoxes[i].Text = dateDict[keyVar[]];
}
The eventTextBoxes part is where im getting stuck on how to pull the value from the nested dictionary, hence why that part of the code is wrong/incomplete.
I can't use tuples as I am using .NET lower than 4 and can't seem to wrap my head around making a custom class to act as its own tuple or multidictionary.

It sounds like you don't need a Dictionary<DateTime, Dictionary<string, string>> since you have only one item inside your inner dictionary, you need a Dictionary<DateTime, Dictionary<string, Event>> where Event is a class that holds you event data. Something like:
public class Event
{
public string Name {get; set;}
public string Guid {get; set;} // you could actually use the GUID type here!
}
Then you'd populate it like:
while (reader.Read())
{
DateTime date = DateTime.Parse(reader["Event_Date"].ToString());
string name = reader["Event_Name"].ToString();
string guid = reader["Event_GUID"].ToString();
dateDict.Add(date, new Event() { Name = name, Guid = guid };
}
Then when you get an item from your dictionary by key:
var item = dateDict[someKey];
You can get your name and guid back:
var name = item.Name;
var guid = item.guid;
Additionally, since you are iterating through your dictionary by numerical index rather than by key, it seems likely that you probably don't need a dictionary at all. Maybe all you need to do is add a Date property to your Event and just have an List<Event>.

I would use a foreach or a LINQ query. But it's not clear what you want as DateTimePicker.Text:
List<DateTimePicker> eventDateBoxes = dateDict
.Select(kv => new{
Date = kv.Key,
EventName = kv.Value["Event_Name"],
EventGuid = kv.Value["Event_GUID"],
})
.Select(x => new DateTimePicker{ Value = x.Date, Text = x.EventName })
.ToList();

This is the basic outline of what you would do:
foreach (var element in dateDict)
{
eventDateBoxes[i].Value = element.Key;
foreach (var subElement in element.Value)
{
eventTextBoxes[i].Text = subElement.Value;
}
}
As others point out in the comment, there can be no one-to-one relationship between the elements in the outer dictionary and the text boxes as there can (potentially) be multiple entries in the sub-element.

Related

How to get first element from Value List of a Dictionary?

I have the following declaration and I need to get the first element from the list using key. Then after assigning that value to some variable again I need to remove that value alone from that list.
Dictionary<string, List<string>> data = new Dictionary<string, List<string>>();
For Example:
List<string> teamMembers = new List<string>();
teamMembers.Add("Country1Player1");
teamMembers.Add("Country1Player2");
teamMembers.Add("Country1Player3");
data.Add("Country1",teamMembers);
teamMembers = new List<string>();
teamMembers.Add("Country2Player1");
teamMembers.Add("Country2Player2");
teamMembers.Add("Country2Player3");
data.Add("Country2",teamMembers);
From the above dictionary, I need to select the Country1 's first element Country1Player1 and assign to some variable. After that I need to remove that value alone from the value list.
Expected output:
If I pass key as 'Country1' then it should give me Country1Player1 and that value needs to be removed the data dictionary. Key Country1 should contain only Country1Player2 & Country1Player3 in the list of values.
string firstTeamMember = null;
if (data.TryGetValue("Country1", out List<string> list) && list?.Any() == true)
{
firstTeamMember = list[0];
list.RemoveAt(0);
}
You could try sth like this:
if(data.TryGetValue("Country1", out var values))
{
var firstValue = values?.FirstOrDefault();
data["Country1"] = data["Country1"]?.Skip(1).ToList();
}

Search a Json object array- List vs Dictionary

I deserialized a JsonResponse using the below code.
var data = (JObject)JsonConvert.DeserializeObject(jsonResponse);
I got the response string which looks something like this
{
"results":[
{
"url":"tickets/2063.json",
"id":20794,
"subject":"Device not working",
"created_date": "2018-01-10T13:03:23Z",
"custom-fields":[
{
"id":25181002,
"value":34534
},
{
"id":2518164,
"value":252344
}
]
}
]
}
My objective is to read certain fields in this array of json objects and insert into a database. The fields i require are id, subject, created_date, member_id.
The member id is part of the custom fields. member_id is the value where id=2518164. I've used List to store this, can you let me know if List or Dictionary is better for this case. How to implement a dictionary
var data = (JObject)JsonConvert.DeserializeObject(jsonResponse);
var tickets = data["results"].ToList();
foreach (var ticketItem in tickets){
Int64? ticketFormId = ticketItem["id"].Value<Int64>();
string subject = ticketItem["subject"].Value<string>();
DateTime createdDate = ticketItem["created_date"].Value<DateTime>();
//Do you think for the next step a dictionary is better or a List is better, since I want to search for a particular id=2518164
var fieldsList = ticketItem["fields"].ToList();
foreach(var fieldItem in fieldList){
Int64? fieldId = fieldItem["id"].Value<Int64>();
if(fieldId!=null && fieldId == 2518164){
memberId = fieldItem["value"].Value<string>();
}
}
}
If you're next step to insert them all into the database, just store them into a list. A dictionary is only useful to search the item by a key.
You can also use linq to process the json in a simpler way:
var tickets = JObject.Parse(jsonResponse)["results"]
.Select(ticket => new
{
Id = (long)ticket["id"],
Subject = (string)ticket["subject"],
CreatedDate = (DateTime)ticket["created_date"],
MemberId = (long)ticket["custom-fields"]
.FirstOrDefault(cf => (int)cf["id"] == 2518164)
?["value"],
})
.ToList();

How to sort a dictionary in the same order of another dictionary in c#

I have two dictionary one composed by:
1) <Id, Name>
This dictionaryis sorted by "Name"
Another dictionary composed by:
2) <Id, ListOfValues>
This dictionary`is not sorted.
I have to sort the second dictionary in the same order of the first, i can use Id as common point, how i can do this?
How i can sort the second dictionary
String json = data as string;
var rawData = JsonConvert.DeserializeObject<List<SectionItem>>(json);
/* New dictionary used to order item for name */
Dictionary<string, string> dataToOrder = new Dictionary<string, string>();
var name ="";
/* Getting data in "local language" */
var local_lang = ConfigurationContext.CurrentLocale;
/* In dataToOrder I insert name and Id*/
foreach (SectionItem si in rawData)
{
name = si.Entities[local_lang].Name;
dataToOrder.Add(name, si.Id);
}
/* List with ordered data by name*/
var orderedData = dataToOrder.OrderBy(kvp => kvp.Key).ToList();
Now I have to order each element of rawdata in the same order of orderedData , how i can do this ?
public class SectionItem
{
public string Id;
public Dictionary<string, EntityGroup> Entities;
}
Assuming you want to sort SecondDictionary based on Key of a dataToOrder, you could do this.
Look for an index of seconddiction Key in the first dictionary and use for Ordering the dictionary..
var ids = dataToOrder.Keys.ToList();
SecondDictionary.OrderBy(x=> ids.Contain(x.Key)? ids.IndexOf(x.Key) : int.MaxValue);

C# - Nested Array/Data structures

Recently, I have been getting into C# (ASP.NET) and moving on from PHP. I want to achieve something like this:
mainArray (
array 1 (
'name' => 'example'
),
array 2 (
'name' => 'example2'
)
);
I know that you can use an Array in C# however, you must indicate the length of the Array before doing so which is where the problem is.
I want to loop through a Database in a Class function which returns an Array of all the columns, ie:
id, username, email.
I have tried:
public Array search_bustype(string match, string forthat)
{
db = new rkdb_07022016Entities2();
var tbl = (from c in db.tblbus_business select c).ToArray();
List<string> List = new List<string>();
int i = 0;
foreach (var toCheck in tbl)
{
if (toCheck.BusType.ToString() == match)
{
if (forthat == "Name")
{
List.Add(toCheck.Name);
}
if (forthat == "Address")
{
}
}
i++;
}
return List.ToArray();
}
But as you can see, I am having to only return the single column because the List is not multidimensional (can't be nested).
What can I use to solve this issue? I have looked at some links:
C# Arrays
StackOverflow post
But these again are an issue for my structure since I don't know how many index's I need in the Array when declaring it - The Database grows everyday.
Thanks in advance.
Try something like this. First, define a class for your business model.
public class Person
{
public string Name {get;set;}
public string Address {get;set;}
}
Then use a generic list instead of a string list.
public Person[] search_bustype(string match, string forthat)
{
var db = new rkdb_07022016Entities2();
List<Person> personList = new List<Person>();
foreach (var toCheck in db.tblbus_business.Where(b => b.BusType.ToString() == match))
{
var model = new Person { Name = toCheck.Name, Address = toCheck.Address };
personList.Add(model);
}
return personList.ToArray();
}
I'm not sure what you are trying to do with the forthat variable.
You can use a list of lists
IList<IList<string>> multiList;

c# How to sort a sorted list by its value column

i have a generic sorted list "results" with key = some filename and value = boolean.
I would like to sort the list by the boolean entry or value column. does anyone know how i can do this?
Thanks!
SortedList is optimized so that inertions occur in an ordered fashion, such that enumeration occurs in a sorted order at minimal cost. Anything else requires a re-sort. Thus:
SortedList<string,bool> l = new SortedList<string, bool>();
l.Add("a", true);
l.Add("b", false);
l.Add("c", true);
l.Add("d", false);
var orderByVal = l.OrderBy(kvp => kvp.Value);
but this enumeration will be significantly slower to calculate, and be performed up-front, requiring extra storage to do so.
Depending on your situation it might be cheaper to maintain 2 SortedList instances with the key/value reversed.
In .NET 2.0, you could add your items to a SortedList:
public static List<MyObject> SortedObjects(IEnumerable<MyObject> myList) {
SortedList<string, MyObject> sortedList = new SortedList<string, MyObject>();
foreach (MyObject object in myList) {
sortedList.Add(object.ValueIWantToSort, object);
}
return new List<MyObject>(sortedList.Values);
}
For descending all list items
list.OrderByDescending();
or
var list = list.OrderByDescending(x => x.Product.Name)
.ThenBy(x => x.Product.Price).ToList();
Normally that sorted by the first key on the list so if you swap the key and value on the add, then match that on the binding
that sample example i use and work fine
public static SortedList<string, string> GetCountries(string conn)
{
var dict = new SortedList<string, string>();
dict.Add("","Select One");
var sql = "SELECT [CountryID] ,[Descr] FROM [dbo].[Countries] Order By CountryID ";
using (var rd = GetDataReader(conn, sql))
{
while (rd.Read())
{
dict.Add(rd["Descr"].ToString(), rd["CountryID"].ToString());
}
}
return dict;
}
Dim List As SortedList(Of String, String) = VDB.CoreLib.DbUtils.GetCountries(connDB)
ddlBankCountry.DataSource = List
ddlBankCountry.DataTextField = "Key"
ddlBankCountry.DataValueField = "Value"
ddlBankCountry.DataBind()

Categories