Put picker selected dictionary value in another picker - c#

I'm having struggles with the following:
I have a Dictionary that gets filled by a webAPI.
Dictionary<string, int> recipients = new Dictionary<string, int>();
And i have a picker
pickerRecipients = new Picker
{
};
foreach (string recipientName in recipients.Keys)
{
pickerRecipients.Items.Add(recipientName);
}
What i want is that with the press of a button, the selected value to be put in a second Dictionary
Dictionary<string, int> multiRecipients = new Dictionary<string, int>();
To add it i used
multiRecipients.Add(KEY, VALUE);
But as far as i know, i could only acces the value, and not the key. I have no idea how to do that. I think the main problem is that i select it from a picker, and not directly from the dictionary.
Many thanks to anybody who can enlighten me (:
p.s. I use Xamarin
edit:
This is what i have now, but i also changed the int to a string, and the string to an int.
if (pickerRecipients.SelectedIndex != -1)
{
string currentlySelected = pickerRecipients.Items[pickerRecipients.SelectedIndex];
var SelectedValue = recipients[currentlySelected];
multiRecipients.Add(currentlySelected, SelectedValue);
}

since you already know the key to item, just use the [key] syntax to retrieve the value:
var SelectedValue = recipients[SelectedKey];
multiRecipients.Add(SelectedKey, SelectedValue);

you can use linq to get the key using the value from the dictionary, it would be like:
var key= recipients.FirstOrDefault(x => x.Value == selectedValue).Key;
multiRecipients.Add(key,selectedValue);

Related

List of strings stored as values in dictionary C#

I have a testing framework that needs to be updated to include testing in Spanish. I have a CSV file that contains the field label, english text, and Spanish text. I've decided to use a dictionary to store the field label as the key and the values would be a list of strings for Spanish and English text.
private List<string> ReadTranslationCsv()
{
var pathToCSV = #"C:\Location";
Dictionary<string, List<string>> translations = new Dictionary<string, List<string>>();
string label, englishText, spanishText;
using (TextReader fileReader = File.OpenText(pathToCSV))
{
var csv = new CsvReader(fileReader);
csv.Configuration.HasHeaderRecord = false;
while (csv.Read())
{
for (int i = 0; csv.TryGetField<string>(i, out label);)
{
List<string> Spanglish = new List<string>();
csv.TryGetField<string>(i + 1, out englishText);
Spanglish.Add(englishText);
csv.TryGetField<string>(i + 2, out spanishText);
Spanglish.Add(spanishText);
if (label != "")
{
translations.Add(label, Spanglish);
}
i = i + 3;
}
}
}
}
I want to be able to search within the list of values to see if anything matches some string of text. I'm not sure how to search the lists that are within the dictionary, none of the default methods or properties are working.
I'm using the below code but this will return me a bool, which is not what I need, I need the list value that matches the elementWithText
public void GivenElementMatches(string elementWithText)
{
if (Config.Language == "Spanish")
{
var list = new List<string> { elementWithText };//must create list in order to pass text to any translations methods
Hooks.translations.ContainsValue(list); // Even though the labels are the key, I need to search for the english text which is index 1 of the list and all values should be returned
}
//TODO
}
My suggestion would be to use a Dictionary with a class you create, inside that class you can have a compare function.
The advantage of this method is you may add more language equivalents later and only have to change your model.
Please note, this code is not complete and you will have to bug check and alter it to suit.
Dictionary <string, LangEquivalents> model;
public KeyValuePair<string, LangEquivalents> findField(string input)
{
return model.First(x=>x.Value.Comparison(input));
}
You could also make it a comparable object type and just use model.First(x=>x.Value == input));

adding new values to dictionary with a list as its value

i have a dictionary like this :
Dictionary<string,List<string>> StudentsByTeacherName = new Dictionary<string,List<string>>();
this dictionary is inside a loop i want the dictionary Value for a specific key get updated in each loop. if there are no new keys there to add to the dictionary
foreach (var item5 in StudentsByTeacherName)
{
if (StudentsByTeacherName.ContainsKey(item5.Key))
{
}
else
{
StudentsByTeacherName.Add(item4.Value,StudentName);
}
}
i want the dictionary Value for a specific key get updated in each
loop. if there are no new keys there to add to the dictionary
For that instead of checking for ContainsKey simply do:
TeacherName[item3.Key] = yourStringList;
The indexer [] will update the existing Key and inserts if the key doesn't exists.
You cannot change your property or indexer value since this is read only. What you can do is access it via its index:
foreach (var item5 in StudentsByTeacherName)
{
if (StudentsByTeacherName.ContainsKey(item5.Key))
{
//This will add new values on your list of string on specific
//keys and will not delete the existing ones:
List<string> list = StudentsByTeacherName[item5.Key];
list.Add("Your additional value here");
}
else
{
StudentsByTeacherName.Add(item4.Value,StudentName);
}
}
This will update the value of string list and not the key itself.
Try this.
foreach (var item5 in StudentsByTeacherName)
{
if(item5.Value == null)
{
item5.Value = new List<String();
}
item5.Value[item4.Key] = item4.Value;
}
I am assuming that item4 is the Student. This will replace an existing value or add a new value.

Get int value from picker using dictionary

Somebody told me that the key of a dictionary should be unique, so i changed my dictionary from:
Dictionary<string, int> recipients = new Dictionary<string, int>();
to
Dictionary<int, string> recipients = new Dictionary<int, string>();
Because the int is unique in my case, and the string isn't per se.
But first i could get the int from a picker aswell, but now i cant figure it out.
The picker:
pickerRecipients = new Picker
{
};
foreach (string recipientName in recipients.Values)
{
pickerRecipients.Items.Add(recipientName);
}
First i would do
string currentlySelected = pickerRecipients.Items[pickerRecipients.SelectedIndex];
But now it obviously doesnt work, but i can't find a way to get the int (the picker shows the string, which is a name, the int thats connected to it is an unique user number)
// get the key of the first match
var key = recipients.FirstOrDefault(x => x.Value == selectedName).Key;
I don't have enough rep to put it as a comment but your code will have problems. For example if u have this values in your dictionary : '1 someValue', '2 otherValue', '3 someValue' and the user will pick '3 someValue'. Your code will return 1.
I think you could try to insert (I entered a SPACE before the ( so i can split by ' ')
foreach (var recipient in recipients)
{
pickerRecipients.Items.Add(recipient.Value + " (" + recipient.Key + ")");
}
then get the user selected value with
string currentlySelected = pickerRecipients.Items[pickerRecipients.SelectedIndex];
split the result like
var selectedIndex = currentlySelected.Split(' ').Last().Split('(', ')')[1];
and you get your selected index.
Again, this is not a direct solution to your problem but your problem will generate other problems if you don't take this into consideration.

assigning dictionary to key values

Dictionary<int, String> loadData = new Dictionary();
// File contains a list of filenames say for ex. 5 filenames
foreach (var file in filenames)
{
// I want to assign like this
loadData[id]=file;
}
How can I assign loadData(key,value) in C# so that I can access like loadData[5] = "hello.txt";
First: You are using new Dictionary() which won't properly work. Use new Dictionary<int, String>() instead.
Second: Where does id come from? If it's just a counter, you can do the following:
Dictionary<int, String> loadData = new Dictionary<int, String>();
int id = 0;
foreach (string file in filenames)
{
loadData.Add(id++, file);
}
if id is just a counter you can use arrays and still can write loadData[5]="hello.txt";
var loadData = filenames.ToArray();
loadData[5]="hello.txt";
Keep a counter.
int i = 0;
foreach (var file in filenames) {
++i;
loadData[i] = file;
}
This assigns the first item in filenames to loadData[1].
I assume by ID, it's not a value in file but the item's index in the loop
filenames.ForEach(x => loadData.Add(loadData.Count, x));
This will give you
Key Value
0 First filename
1 Second filename
2 Third filename
etc...
If I understand correctly, this is what you want. Or do you have a separate Key and want to access the dictionary by some sort of index (like a List)?
This is very easy.
You can use this.
loadData.Add(1,"fileName1");
Or You Put this line inside loop.
Another way of doing it.
var loadData = fileNames
.Select((fn,index)=> new {key = index, value = fn})
.ToDictionary(x=> x.key, x=> x.value);
Using the ToDictionary() extension method...
int id = 1;
var loadData = filenames.ToDictionary(x => id++);

get unique values from query to build Dictionary

I want to build a combobox with key->postal and value->city to use as filter for my accomodations.
To limit the number of items in the list I only use the postals I have used when filling up the table tblAccomodations.
For now I do not use a relational table with postals and city's although I'm thinking about an update later on.
Here I build my dictionary:
public static Dictionary<int, string> getPostals()
{
Dictionary<int, string> oPostals = new Dictionary<int, string>();
using (DBReservationDataContext oReservation = new DBReservationDataContext())
{
var oAllPostals = (from oAccomodation in oReservation.tblAccomodations
orderby oAccomodation.Name ascending
select oAccomodation);
foreach (tblAccomodation item in oAllPostals)
{
oPostals.Add(int.Parse(item.Postal), item.City);
}
}
return oPostals;
}
As expected I got an error: some Accomodations are located in the same city, so there are double values for the key. So how can I get a list of unique cities and postals (as key)?
I tried to use
select oAccomodation.Postal.Distinct()
but that didn't work either.
UPDATE: I have found the main problem. There are multiple cities with the same postal ("Subcity"). So I'm gonna filter on "City" and not on "Postal".
I think your looking for 'Distinct'. Gather your list of all postals and then return myPostals.Distinct().
Hope than helps.
change
foreach (tblAccomodation item in oAllPostals)
{
oPostals.Add(int.Parse(item.Postal), item.City);
}
to
foreach (tblAccomodation item in oAllPostals.Distinct(x=>x..Postal)
{
if(!oPostals.ContainsKey(int.Parse(item.Postal)))
oPostals.Add(int.Parse(item.Postal), item.City);
}
BTW, if you have multiple cities in one postal (I am not sure if it is possible in your domain), which one you want to see?
If any of cities will do, then it is easy to just get the first one per postal:
var oAllPostals = oReservation.tblAccomodations
.OrderBy(x=>x.Name)
.ToLookup(x=>x.Postal, x=>x.City)
.ToDictionary(x=>x.Key, x.First());
In the same example if you do .ToList() or even .Distinct().ToList() instead of .First() you will have all of cities in the dictionary of Dictionary<Postal, List<City>>.
Assuming the combination of postal + city is unique you could do the following:
public static Dictionary<int, string> getPostals()
{
Dictionary<int, string> oPostals = new Dictionary<int, string>();
using (DBReservationDataContext oReservation = new DBReservationDataContext())
{
var oAllPostals = (from oAccomodation in oReservation.tblAccomodations
orderby oAccomodation.Name ascending
select oAccomodation);
foreach (tblAccomodation item in oAllPostals)
{
oPostals.Add((item.Postal + item.City).GetHashCode(), item.Postal + " " + item.City);
}
}
return oPostals;
}
Edit:
If you want to use the selected value from the drop box then you can use the following:
public static Dictionary<int, Tuple<string, string>> getPostals()
{
Dictionary<int, string> oPostals = new Dictionary<int, string>();
using (DBReservationDataContext oReservation = new DBReservationDataContext())
{
var oAllPostals = (from oAccomodation in oReservation.tblAccomodations
orderby oAccomodation.Name ascending
select oAccomodation);
foreach (tblAccomodation item in oAllPostals)
{
oPostals.Add((item.Postal + item.City).GetHashCode(), new Tuple<string, string>(item.Postal, item.City));
}
}
return oPostals;
}
The way you bind the following depends on whether you're using asp.net, winforms etc. Here's an example for winforms.
Using .containkey will exclude [1 (postal key) to n (cities relation)]. i.e since Key already exists next city (with the same postal key ) will not get into your dictionary.
However, if you want to map your postal to list of cities, you can represent a dictionary that can contain a collection of values like the following:
Dictionary < String[Postal]> , List < Cities>>
This way you'll have a dictionary that can have multiple values.

Categories

Resources