Sort Dictionary Array - c#

I have Following Array an want to sort it by the time key:
Dictionary<string, object>[] callHistory = CharactersPhone.CharactersPhoneCallHistorys_.ToList().Where(x => x.charPhoneNumber == Characters.GetCharacterPhonenumber(charId)).Select(x =>
new Dictionary<string, object>
{
{"charPhoneNumber" , x.charPhoneNumber.ToString()},
{"targetPhoneNumber" , x.targetNumber.ToString()},
{"state" , x.state},
{"outgoingstate", x.outgoingState},
{"time" , x.timestamp.ToString("dd.MM.yyyy HH:mm")}
}).ToArray();
I try it with the following:
var sorted = callHistory.OrderBy(x => Array.IndexOf(callHistory, x.time))
but the key "x.time" is not found, i think i have a little brain lag here or something is fundamental wrong but i doesnt find the answer. Maybe someone here can help.

For dictionaries you need to use the indexer:
var sorted = callHistory.OrderBy(x => x["time"])
I would also note that this sorts it by the string values since that's what you use to create the dictionary. I would either keep it as a time and only convert to string when you display the data, or store the date/time in a sortable format (e.g. yyyy-MM-dd hh:mm)

You're trying to access a keyed value as though it were a property or field.
Instead of accessing it with the . operator, use the index operator, as shown below:
var a = new Dictionary<string, object>
{
{"charPhoneNumber" , 'a'},
{"targetPhoneNumber" , 'b'},
{"state" , 'c'},
{"outgoingstate", 'd'},
{"time" , 'e'}
};
var b = a["time"];
Console.WriteLine(b); // Outputs "e"
In your case, you'd use x["time"] in place of x.time.

Related

C# create an array from specific values of dictionnary

I've been looking for answers but for some reasons all I found doesn't match with my use.
I'm not very familiar to c#, I have a dictionary
public Dictionary<int, int> deck = new Dictionary<int, int>();
I want to take ten first values of this dictionary and put it in an array like
public string[] cardP1 = new string[10];
, I tried some things with .Take or .CopyTo, I also played with the Values but it is still not working.
you can use LINQ very easily like this :
var q = (from p in deck.Keys select p).Take(10).ToArray();
if you want Values you can just change the deck.keys to deck.values
it will give you the 10 first keys.
EDIT Or as Jakub DÄ…bek commented :
var items = deck.Keys.Take(10).ToArray();
Check this:
if(deck.Count>=10)
{
cardP1 = deck.Take(10).Select(x => x.Value.ToString()).ToArray();
}
Or if you want to have some custom string for example: Card 1: 4
you can go with:
cardP1 = deck.Take(10).Select(x => string.Format("Card {0}: {1}", x.Key, x.Value) ).ToArray();

Suggested structure to maps some strings to some other strings

In my console application I have one hundred county codes and their names. For example:
"01" : "Floyd"
"02" : "Wabash"
When my program uses the values, it reads "01","02"...and I want to get "Floyd", etc...
This list won't grow in future, I am just hard coding them, How do you suggest to access these?
Maybe in a static class? Maybe in a JSON format? Other ways?
Dictionary is what you look for: MSDN link
Short example:
void Main()
{
var dic = new Dictionary<int,string>();
// Instead of having a method to check, we use this Action
Action<int> tryDic = (i) => {
if (dic.ContainsKey(i))
Console.WriteLine("{0}:{1}", i, dic[i]);
else
Console.WriteLine("dic has no key {0}", i);
};
dic.Add(1,"one");
dic.Add(2,"two");
// dic.Keys = 1, 2
// dic.Values = one, two
tryDic(1); // one
tryDic(3); // dic has no key 3 (Happens in Action above)
dic[1]="wow";
tryDic(1); // wow
}
Just use a simple Dictionary<string, string>; if you really want you can wrap it in a class to add some behavior such as handling keys not found, or already existing
You are looking for a Dictionary<string, string>
var values = new Dictionary<string,string>();
values.Add("01", "Floyd");
...
var value = values["01"]; // Floyd

How to get value from dictionary without knowing key?

I want to get value from dictionary but i don't know key(Because dynamic generate dictionary from database) how can i get dictionary value.
If you some idea share me ...
For Example my database string value like
string jsonString = " "FB": "[{\"title\":\"sheet1\",\"rows\":[{\"height\":\"undefined\",\"columns\":[{\"value\":\"Cover Group \"},{\"value\":\"Sample Variable\"},{\"value\":\"Coverpoint Name\"},{\"value\":\"Crossed cover points\"},{\"value\":\"Coverpoint Comment\"},{\"value\":\"Bin Type\"},{\"value\":\"Bin Id\"},{\"value\":\"Sample Value\"},{\"value\":\"Expected Bin Count\"},{\"value\":\"Set Max Bin\"},{\"value\":\"Not Used\"}]},{\"height\":\"undefined\",\"columns\":[{\"value\":\"allCg,allSi\"},{\"value\":\"exSingle\"},{\"value\":\"exSingle\"},{},{\"value\":\"Example for single bin\"},{\"value\":\"single\"},{\"value\":\"valZero\"},{\"value\":\"1'b0\"},{\"formula\":\"1\",\"value\":1},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{},{},{},{\"value\":\"single\"},{\"value\":\"valOne\"},{\"value\":\"1'b1\"},{\"formula\":\"1\",\"value\":1},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{\"value\":\"ex1Bus[3:0]\"},{\"value\":\"exMulti\"},{},{\"value\":\"Example for multibin\"},{\"value\":\"multi\"},{},{\"value\":\"[0:15]\"},{\"formula\":\"16\",\"value\":16},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{\"value\":\"exCross\"},{\"value\":\"exSingle,exMulti\"},{\"value\":\"Example for cross\"},{\"value\":\"Implicit\"},{},{},{\"formula\":\"32\",\"value\":32},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{\"value\":\"ex2Bus[15:0]\"},{\"value\":\"exWildcard\"},{},{\"value\":\"example for wildcard\"},{\"value\":\"wildcard\"},{\"value\":\"ex_wildcard\"},{\"value\":\"16'bxxxxxxxxxxxxxx1\"},{\"formula\":\"1\",\"value\":1},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{\"value\":\"ex3Bus[4:0]\"},{\"value\":\"exImplicit\"},{},{\"value\":\"example for implicit & set max bin\"},{\"value\":\"Implicit\"},{},{},{\"formula\":\"8\",\"value\":8},{\"formula\":\"8\",\"value\":8},{}]},{\"height\":\"undefined\",\"columns\":[{},{\"value\":\"ex4Bus[3:0]\"},{\"value\":\"ex4Bus\"},{},{\"value\":\"setup for ignore example\"},{\"value\":\"multi\"},{},{\"value\":\"[0:15]\"},{\"formula\":\"16\",\"value\":16},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{\"value\":\"exIgnore\"},{\"value\":\"exSingle,ex4Bus\"},{\"value\":\"example for ignore\"},{\"value\":\"ignore\"},{},{\"value\":\"ex4Bus([12:15])\"},{\"formula\":\"24\",\"value\":24},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{\"value\":\"ex5Bus[3:0]\"},{\"value\":\"exIllegal\"},{},{\"value\":\"example for illegal\"},{\"value\":\"illegal\"},{},{\"value\":\"[12:15]\"},{\"formula\":\"16\",\"value\":16},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{},{},{},{},{},{},{},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{},{},{},{},{},{},{},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{},{},{},{},{},{},{},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{},{},{},{},{},{},{},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{},{},{},{},{},{},{},{},{}]}],\"metadata\":{\"widths\":[\"200\",\"200\",\"200\",\"200\",\"200\",\"200\",\"200\",\"200\",\"200\",\"200\",\"200\"],\"frozenAt\":{\"row\":0,\"col\":0}}}]""
FB is dynamic key and after it's value title all value i need
If you don't have the key, but have the value and trying to get hold of the key, you can do this:
Dictionary<string, string> testData = new Dictionary<string, string>();
testData.Add("name", "Latheesan");
testData.Add("age", "26");
KeyValuePair<string, string> searchResult
= testData.FirstOrDefault(s => s.Value == "Latheesan");
string key = searchResult.Key; // returns "name" here
To get a sequence of all the Key/Value pairs where the value matches a target:
var dict = new Dictionary<string, int>
{
{"One", 1},
{"Two", 2},
{"Another One", 1},
{"Three", 3},
{"Yet Another One", 1}
};
int target = 1; // For example.
var matches = dict.Where(item => item.Value == target);
foreach (var kvp in matches)
Console.WriteLine("Key = " + kvp.Key);
The sample data you posted isn't a flat key-value dictionary. It contains embedded dictionaries - the base dictionary contains a title and a rows, which in turn consists of height and columns and so on, and at some point are key-value pairs who keys are, confusingly, named 'value'. Are you asking how to parse this data structure to get all the values whose key is value?
What you first need to do, since this appears to be a JSON-formatted entry, is parse the JSON into a .NET data structure, using libraries like JSON.NET or System.Web.Helpers.Json. These libraries will convert the JSON string into a hierarchy of dictionaries, all of them implementing IEnumerable, so you can iterate over it, more or less like this (this is not compilable code, just a demonstration!):
public void Main()
{
var jsonObject = Json.Decode(FB); // FB is your JSON string.
var values = new List<string>();
FindValues(jsonObject);
}
public void FindValues(jsonObject, values)
{
foreach (var child in jsonObject)
{
if (child.key == 'value')
{
values.Add(child.value);
}
// Recursively call FindValues on child objects.
FindValues(child, values);
}
}
This C#-ish pseudo-code shows you how to go over a dictionary, then optionally drill down deeper into internal dictionaries.
This code use for get value from dictionary value without knowing key and value..
var json = Newtonsoft.Json.JsonConvert.SerializeObject(jsonString );
var javSer = new JavaScriptSerializer();
var dfi = javSer.Deserialize<Dictionary<string, string>>(json);
string dataString= dfi.Values.First();
How can you possibly know which value you need if you don't have the key?
A Dictionary in .NET does contain a Keys and Values collection, so if you are only interested in the values, you can use that.

C# Convert List<string> to Dictionary<string, string>

This may seem an odd thing to want to do but ignoring that, is there a nice concise way of converting a List<string> to Dictionary<string, string> where each Key Value Pair in the Dictionary is just each string in the List. i.e.
List = string1, string2, string3
Dictionary = string1/string1, string2/string2, string3/string3
I have done plenty of searching and there are literally dozens of examples on Stackoverflow alone of doing it in the opposite direction but not this way round.
The reason for doing this is I have two third part components and changing them is out of my hands. One returns a list of email addresses as a List<string> and the other send emails where the To parameter is a Dictionary<string, string>. The key of the dictionary is the email address and the value is their real name. However, I don't know the real name but it still works if you set the real name to the email address as well. Therefore why I want to convert a List to a Dictionary<string, string>. There are plenty of ways of doing this. A foreach loop on the list which adds a kvp to a dictionary. But I like terse code and wondered if there was a single line solution.
Try this:
var res = list.ToDictionary(x => x, x => x);
The first lambda lets you pick the key, the second one picks the value.
You can play with it and make values differ from the keys, like this:
var res = list.ToDictionary(x => x, x => string.Format("Val: {0}", x));
If your list contains duplicates, add Distinct() like this:
var res = list.Distinct().ToDictionary(x => x, x => x);
EDIT To comment on the valid reason, I think the only reason that could be valid for conversions like this is that at some point the keys and the values in the resultant dictionary are going to diverge. For example, you would do an initial conversion, and then replace some of the values with something else. If the keys and the values are always going to be the same, HashSet<String> would provide a much better fit for your situation:
var res = new HashSet<string>(list);
if (res.Contains("string1")) ...
Use this:
var dict = list.ToDictionary(x => x);
See MSDN for more info.
As Pranay points out in the comments, this will fail if an item exists in the list multiple times.
Depending on your specific requirements, you can either use var dict = list.Distinct().ToDictionary(x => x); to get a dictionary of distinct items or you can use ToLookup instead:
var dict = list.ToLookup(x => x);
This will return an ILookup<string, string> which is essentially the same as IDictionary<string, IEnumerable<string>>, so you will have a list of distinct keys with each string instance under it.
EDIT
another way to deal with duplicate is you can do like this
var dic = slist.Select((element, index)=> new{element,index} )
.ToDictionary(ele=>ele.index.ToString(), ele=>ele.element);
or
easy way to do is
var res = list.ToDictionary(str => str, str=> str);
but make sure that there is no string is repeating...again otherewise above code will not work for you
if there is string is repeating than its better to do like this
Dictionary<string,string> dic= new Dictionary<string,string> ();
foreach(string s in Stringlist)
{
if(!dic.ContainsKey(s))
{
// dic.Add( value to dictionary
}
}
By using ToDictionary:
var dictionary = list.ToDictionary(s => s);
If it is possible that any string could be repeated, either do a Distinct call first on the list (to remove duplicates), or use ToLookup which allows for multiple values per key.
You can use:
var dictionary = myList.ToDictionary(x => x);

loop one sequence and check againt other list

i have a namespace string like "Company.Product.Sub1.Sub2.IService".
The Sub1/Sub2 can differ in their count, but normally their is one part which matches to
a Dictionary with AssemblyFullname as key and path to it as value.
Now ive written this code
string fullName = interfaceCodeElement.FullName;
var fullNameParts = interfaceCodeElement.FullName.Split('.').Reverse();
KeyValuePair<string, string> type = new KeyValuePair<string,string>();
foreach (var item in fullNameParts)
{
var match = references.Where(x => x.Key.Contains(item)).ToList();
if (match.Count > 0)
{
type = match[0];
break;
}
}
Works but doesnt look nice in my opinion.
I tried it with linq but i dont know how ive to write it.
var matches = from reference in refs
where reference.Key.Contains(fullNameParts.Reverse().
Thanks for help.
To first put it into English, you're trying to go through the parts (backwards) of the Fullname in interfaceCodeElement and find the first that matches (as a substring, case-sensitive) any of the keys in references (which is a Dictionary<string, string> from fullname to path). Your result, type, is a KeyValuePair<string, string> although it's not clear if you actually need that (both the key and value) or just one or the other.
One, it seems a little odd to have a Dictionary in such a case, since you're not able to lookup as a key, but I guess it still works for the purpose :) Switching to something like List<Tuple<string, string>> or List<KeyValuePair<string, string>> might make sense, as the order of the pairs that comes from iteration over references will potentially affect which pair is selected into type.
In order to try to make it easier to understand, I'll add a let here:
var bestMatchPerPart = from part in fullNameParts
let firstMatchPair = references.FirstOrDefault(pair => pair.Key.Contains(part))
where firstMatchPair != null // ignore parts that have no match
// since we want the pair, not the part, select that
select firstMatchPair;
var type = bestMatchPerPart.FirstOrDefault()
// to match original behavior, empty pair in result instead of null if no match
?? new KeyValuePair<string, string>();
This should give you a list of the matches:
var listOfMatches = fullNameParts.Where(fp => references.Where(r => r.Key.Contains(fp))).ToList();
Edit: So based on your comments I think I kind of understand. Assuming you have some list of these fullNames somewhere:
// Making this up because I am nor sure what you have to start with
List<string> yourListOfAllYourFullNames = GetThisList();
var listOfMatches = yourListOfAllYourFullNames.Where(
fnl => fnl.Split('.').Reverse().Where(
fnp => references.Where(r => r.Key.Contains(fnp))).Count() > 0).ToList();

Categories

Resources