I'm currently working on a game in which the top 5 highscores can be displayed on a highscores page.
Currently i have a dictionary of type [string, int] which will store the user's name and score respectively.However, i'm having trouble creating a method that will take all 5 dictionary elements in the format of {"name", 20} and assign each element to a string.
For example, dictionary element[0] contains the value {sam, 20}. I would like to assign this element to a string that would read "sam 20".
At the moment i have a method which will return the top5 highscores but my problem occurs when turning these values into strings from dictionary elements.
Any help would be appreciated and if you have any questions, please don't hesitate to ask.
Thanks in advance.
You can use .Select() and string interpolation to build out a projected string list:
var formattedStrings = dict
.OrderByDescending(x => x.Value)
.Select(x => $"{x.Key} {x.Value}").ToList();
Since Dictionary<TKey, TValue> implements IEnumerable<KeyValuePair<TKey, TValue>>, we can easily use LINQ to both order and project our key/value pairs before interpolating them into a new string.
This also allows for more flexible querying before projecting your list.
try this.
var answer= string.Join(",", map.Select(s => s.Key + " " +s.Value).ToArray());
Related
I have a dictionary which holds strings as keys and Lists as values. Imagine you have Olympic Games where the keys are different countries and the values in each list are for example number of participants, number of sports, gold medals, silver medals, etc. So if I want to sort the countries by gold medals and say gold medals is the second entry in each list I would want something like this:
var countryRankings = new Dictionary<string, List<int>>();
countryRankings.Add(country, new List<int>() {numberOfParticipants, numberOfWins });
//some more country data follows
countryRankings.OrderByDescending(pairs => pairs.Value[1]);
The last bit is not rejected by VisualStudio but is not working as expected. The dictionary is not sorted.When I think about it it's better to create class country with different properties and then sort with Lambda in the way OrderBy(c => c.goldMedals) but is there a way to do this with nested inside a dictionary List ?
That's because the OrderByDescending extension method does not mutate (modify) the original object (countryRankings) but instead returns another object that, when enumerated, produces ordered references to elements in the original dictionary.
So, this should work:
var orderedRankings = countryRankings.OrderByDescending(pairs => pairs.Value[1]);
// now you can iterate over orderedRankings
foreach(var rankingPair in orderedRankings)
{
// do something with it..
}
And, yes it would be better to create a class as you suggested in the last part of the question but that doesn't change the answer.
The OrderByDescending method doesn't sort the dictionary, it returns a new collection that is sorted.
Assign the result to a variable. It can't be a dictionary though, as the items in a dictionary can't be reordered. You can use the ToList method to realise the result as an actual collection:
List<KeyValuePair<string, List<int>>> result =
countryRankings.OrderByDescending(pairs => pairs.Value[1]).ToList();
Using a class instead of a list of integers would be better, but it doesn't change what you need to do to get the sorted result, only what the expression to sort it looks like.
I am writing code that will select string keys from an array ApiIds that are not property ApiId of results objects.
I wrote the following code, but it looks redundant to me, is there a way to combine this into one statement and not convert a HashSet of objects into another HashSet of Strings?
var resultsCached = new HashSet<string>(results.Select(x => x.ApiId));
var missingResults = apiIds.Select(x => !resultsCached.Contains(x));
Thanks.
Except will give you the items that aren't in the other collection:
var missingResults = apiIds.Except(results.Select(x => x.ApiId));
Another efficient O(n) approach is to use HashSet.ExceptWith which removes all elements from the set which are in the second sequence:
HashSet<string> apiIdSet = new HashSet<string>(apiIds);
apiIdSet.ExceptWith(results.Select(x => x.ApiId));
The set contains only strings which are not in results now.
So basically I'm having an issue with the task I've been given. I won't bore you with the details of the task itself so I'll just give you the relevant info.
I have a dictionary that I need to be sorted by the int[value] that is the highest, well the top five highest to be precise and I need to be able to show the bottom five as well.
Dictionary<string, int> dict = new Dictionary<string, int>();
The strings(keys) hold words that have been read for a text file. The ints (values) hold ints of how many times they were mentioned in the document.
I was going to do it in another way but I was told to do it with a dictionary so please dictionary only help.
I would appreciate it if you can explain how it should be done so I can learn as well as complete the task as the aim of the task is to educate myself but I'm finding it a bit hard..
I appreciate all your help in advance, if more info is required please let me know and I'll post it!
Dictionaries do not have any inherent order. But if you want to get the top 5 entries with highest (or lowest) values, you can use a little Linq:
using System.Linq;
...
var top5 = dict.OrderByDescending(pair => pair.Value).Take(5);
var bottom5 = dict.OrderBy(pair => pair.Value).Take(5);
This will return an IEnumerable<KeyValuePair<string, int>>. To turn it back into a dictionary, again Linq can help. For example:
var top5 = dict.OrderByDescending(pair => pair.Value).Take(5)
.ToDictionary(pair => pair.Key, pair => pair.Value);
Now, top5 is a Dictionary<string, int> which contains only the 5 elements from dict with the hightest value.
You need to get ordered result from your dictionary, Since you are looking for Top 5, you will need Take like:
//Top 5
foreach (var item in dict.OrderByDescending(r => r.Value).Take(5))
{
Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);
}
The reason you need an OrderBy is because:
Dictionary<TKey, TValue> Class
For purposes of enumeration, each item in the dictionary is treated as
a KeyValuePair structure representing a value and its
key. The order in which the items are returned is undefined.
If you are using C# 3.0 and higher
You can do something like this with LINQ
foreach (KeyValuePair<string,int> item in keywordCounts.OrderBy(key=> key.Value).Take(5))
{
// do something with item.Key and item.Value
}
If you are using C# 2.0
List<KeyValuePair<string, string>> myList = aDictionary.ToList();
myList.Sort((firstPair,nextPair) =>
{
return firstPair.Value.CompareTo(nextPair.Value);
}
);
or it can be rewritten as
myList.Sort((x,y)=>x.Value.CompareTo(y.Value));
LINQ allows for great flexibility in that you can select the top 10, 20 10% etc. Or if you are using your word frequency index for type-ahead, you could also include StartsWith clause as well.
In windows phone, I retrieved a table in database as dictionary in LINQ. My dictionary is like this
Dictionary<int, StudentTable>
I retrieved the table from LINQ as
var studentDictionary = studContext.StudentList.Select(p => new { p.RollNo, p }).AsEnumerable().ToDictionary(kvp => kvp.RollNo, kvp => kvp);
But I want to get all the values in the studentDictionary as a
List<StudentTable>
I know it is possible by adding each dictionary values to the list by using for loop.
How can I do this without a loop. ?
Is there any other better method than a loop?
Thanks
You can use studentDictionary.Values.
PS: The same works for the keys, using studentDictionary.Keys
Your dictionary contains Value which is an object of type StudentTable. You can select that from the dictionary and apply ToList method.
var list = studentDictionary.Values.ToList();
or
var list = studentDictionary.Select(r => r.Value).ToList();
i have 2 different types of dictionaries Dictionary<int, Fooclass> oldDic and Dictionary<int, string> barList newDic . Now i need to compare values in both dictionaries. for Example key can be in
oldDic : 1,2,3
newDic : 1,2,3,4
Expected Output : 4
Now i need to compare both dictionaries on basis of their keys
any help would be appreciated.
Edit :
Output should be like second dictionary(newDic) but this will contain some value of 2nd dictionary's(oldDic). For example
1,"fooString" Where fooString is some value in Fooclass's someproperty....
For more clarity see this which doesn't worked for me
var addedList = from list1 in baseListDic
join list2 in trackerlist on list1.Key equals list2.Key
select new { key = list1.Key, value = list1.Value._lead };
here baseListDic is oldDic and trackerlist is newDic....
Let me know if i'm still not clear...
It would be easier to just create a new dictionary based on the new dictionary ignoring items that have the same key in the old dictionary.
var result = newDic
.Where(kvp => !oldDic.ContainsKey(kvp.Key))
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
Note: Despite your question saying "i need to compare values in both dictionaries" (emphasis mine) your example seems to be demonstrating just comparison of keys so I've gone with that. If it is values you need to compare you might want to give an example of what you mean and if they are easily convertible or comparable...
If you are only actually comparing the keys then you can just use the .Keys property of the dictionary which returns an IEnumerable<TKey> that you can do your linq on...
eg:
var expectedOutput = newDic.Keys.Except(oldDic.Keys);
This does rely on the key being the same type but this goes without saying if you are comparing. Of course, there is nothing stopping you from converting their types first if you do wnat to do this with different types.
Also if you wanted to then get the values in one of the dictionaries you could do something like:
var newDicValues = expectedoutput.Select(x=>newDic[x]);
Or, you know, do any other linqy stuff you feel like. :)
Try this to get the difference between two different list: If they have any common property.
var differentItems = List<Type1>.Select(d => d.Name)
.Except(List<Type2>.Select(d => d.Name));
If understood correctly, try something like this
if you have a separate dictionary moething like this Dictionary<int, Fooclass> FinalDict
IEnumerable<int> list = OldDic.Keys.Except(NewDic.Keys);
foreach (var x in list)
{
var value =new MyClass();
OldDic.TryGetValue(x,out value );
FinalDict.Add(x,value);
}
So in the Dictionary called FinalDict will have the key and related Fooclass
Hope this helps