I have this:
public class GraphicsDraw
{
public Dictionary<int,GraphicItem> items { get; set; }
}
public abstract class GraphicItem
{
public float ItemSize { get; set; }
}
And I can access to all ItemSize's like this:
{
GraphicsDraw gd = new GraphicsDraw();
gd.items[i].ItemSize;
}
Is there any nice way that I can list ItemSize's down separately in another dictionary whit same key and ItemSize values?
Dictionary<int, float> ItemSize = items.(???)
Sure, using ToDictionary:
items.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ItemSize);
You can do, which uses LINQ,
Dictionary<int,float> itemSizes =
items.ToDictionary(item => item.Key, item => item.Value.ItemSize);
The ToDictionary accepts two delegates (or lambda expressions), the first one to select the key and the second one to select the value of the dictionary.
In your case you want to keep the same key, but change the value to the ItemSize property, thus the second expression.
You can simple use LINQ to extract necessary keys and values from items property.
items.ToDictionary(x => x.Key, x => x.Value.ItemSize);
Related
I have the list like this
public class Col
{
public long Id { get; set; }
public Dictionary<string, dynamic> Dt { get; set; }
}
var list = IEnumerable<Col>;
I need to sort the List using dictionary
I tried a lot of methods, but nothing helps, there is an error:
System.ArgumentException: At least one object must implement IComparable.
The last thing I stopped at was:
list.OrderBy(x => x.Dt.Where(r => r.Key == "Smile").Select(r => r.Value));
Sorting should be done by the Dictionary value
Update1:
I want to sort the block that I have selected, but sort not by Id, but by the data in the dictionary
Try this:
list.OrderBy(c => c.Dt[<YourKeyValue>]);
I wrote the code below to get all the values from a dictionary which has the given key.
Dictionary<string,string> _dictionary;
public List<string> GetValuesUsingKey(string key)
{
List<string> outp = new List<string>();
foreach(var d in _dictionary)
{
if (d.Key == key)
{
outp.Add(d.Value);
}
}
return outp;
}
is there a simpler way to achieve this result using LINQ?
Update :
it turned out that i was mislearned about Dictionaries, i though i could use multiple values for a single key but i was wrong
A key in a Dictionary is guaranteed to be unique, so there's no need to return a List.
public string GetValueUsingKey(string key)
{
bool isKeyPresent = _dictionary.TryGetValue(key, out var output);
return isKeyPresent ? output : _YOUR_DEFAULT_BEHAVIOUR_;
}
The big advantage of a Dictionary is that the time complexity for insertion and retrieval of values using the key is O(1); if you cycle through all the KeyValuePair it contains you completely nullify the purpose of using a Dictionary as it would make the retrieval O(n)!
Dictionary is a one to one map, you cannot have multiple values for a given key.
ILookup on the other hand supports this scenario, as well as null keys:
using System.Linq;
class Element
{
public string Key { get; }
public string Value { get; }
...
}
IEnumerable<Element> elements = ...
ILookup<string, string> lookup = elements.ToLookup(e => e.Key, e => e.Value);
and then to get your result:
List<string> outp = lookup[key].ToList();
I am attempting to sort a List of objects (A tree structure) using this Dictionary;
Dictionary<Tuple<int, int>, int?>
The Tuple contains two IDs, which identify a unique object. The value is the sort order.
The object has a similar structure to
public class DmsSortOrder : IRecord
{
public int TagID { get; set; }
public int ObjectID { get; set; }
public int? Order { get; set; }
}
I need to sort a
List<DmsSortOrder>
according to the Dictionary above.
Dictionary<Tuple<tagID, objectID>, sortOrder>()
I need to sort the list of objects according to the values in the dictionary, but I am unsure how. If it matters, the list is actually a list of lists, but I feel comfortable in using recursion to sort the whole List, once I can sort a single branch.
Any assistance would be appreciated.
I guess you want a query like this:
lists = lists
.Select(list => list
.Select(x => new {Key = Tuple.Create(x.TagID, x.ObjectID), DmsSortOrder = x})
.OrderBy(x => dict.ContainsKey(x.Key) ? dict[x.Key] : int.MaxValue)
.Select(x => x.DmsSortOrder)
.ToList())
.ToList();
Change the value int.MaxValue if you don't want to see the unknown objects at the end.
List<MyObject> list; // MyObject has Id1, Id2
Dictionary<Tuple<int, int>, int?> dict;
var sortedObjects =
dict.OrderBy(kvp=>kvp.Value))
.Select(kvp=>
list.Single(obj =>
obj.Id1 == kvp.Key.Item1
&& obj.Id2 == kvp.Key.Item2
)
);
Given these variables:
List<UniqueObject> list;
Dictionary<Tuple<int, int>, int?> sortOrders;
You should end up with something like this:
var sortedList = list.OrderBy(obj => sortOrders[new Tuple(obj.Id1, obj.Id2)]).ToList();
I'm sure there a lot of ways to optimize this, but general idea is rather simple.
If you want to sort the list according to the values in the dictionary you can do it doing this:
List<DmsSortOrder> list = ...
Dictionary<Tuple<int, int>, int> sortOrder = ...
list.Sort((x, y) => sortOrder[Tuple.Create(x.TagID, x.ObjectID)] -
sortOrder[Tuple.Create(y.TagID, y.ObjectID)]);
//or
list = list.OrderBy(o => sortOrder[Tuple.Create(o.TagID, o.ObjectID)]).ToList();
I am using c# WPF for developing a Windows Application.
The application requires a class as follows
public class Limits
{
public String col1
{
get;
set;
}
public String col2
{
get;
set;
}
public String col3
{
get;
set;
}
}
I am using a List to Store Objects like:-
List myList<Limits> = new List<Limits>();
"myList" has around 15000 Objects.
Now, I want to search this myList for a particular attribute.
Eg: I want to find out the object that has col1 set as "abc".
How can I use Binary Search for this problem?
First of all, the list has to be sorted on the col1 property for you to be able to use binary search at all.
You would need a comparer that compares the col1 property:
public class LimitsComparer : IComparer<Limits> {
public int Compare(Limits x, Limits y) {
return x.col1.CompareTo(y.col1);
}
}
Then you can use that to do the binary search:
int index = myList.BinarySearch(new Limits { col1 = "abc" }, new LimitsComparer());
The index returned is:
The zero-based index of item in the sorted List, if item is found;
otherwise, a negative number that is the bitwise complement of the
index of the next element that is larger than item or, if there is no
larger element, the bitwise complement of Count.
You can also use the Where method to get the objects that has that property:
List<Limits> result = myList.Where(x => x.col1 == "abc").ToList();
Although that is not quite as efficient, you should still consider if that is a better solution as it's easier to implement and gives a result that is easier to handle. Also (and this might be more important), it works even if the list isn't sorted on col1.
You could use somthing like this.
myList.Where(i => i.col1 == "abc").ToList();
Use a dictionary where the keys are stored in a hash table. Linq will create the cdictionary easily.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication41
{
class Program
{
static void Main(string[] args)
{
List<Limits> myList = new List<Limits>();
//dictionary with unique keys
Dictionary<string, Limits> dict1 = myList.AsEnumerable()
.GroupBy(x => x.col2, y => y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
//dictionary with keys having multiple values
Dictionary<string, List<Limits>> dict2 = myList.AsEnumerable()
.GroupBy(x => x.col2, y => y)
.ToDictionary(x => x.Key, y => y.ToList());
Limits abc = dict1["abc"];
}
}
public class Limits
{
public String col1 { get; set; }
public String col2 { get; set; }
public String col3 { get; set; }
}
}
unless you explicitly want to use binary search, you should use the standard Linq functions available to you. Unless your list is already sorted, this might be more efficient than binary sort.
var myList = new List<Limits> {....}
var entry = myList.Where(l => l.col1== "abc").FirstOrDefault();
if(entry == null)
{ // no match found }
If you really want binary search, ref Can LINQ use binary search when the collection is ordered?
I have a Dictionary that contains thread Information Dictionary<String,Thread>
"2FF"
"2IE"
"7CH"
etc
what i know is integers 2,7 etc what i want to know that in Dictionary how many strings contain the given integer if it is there then get that string
Eg
String GetString(int integer)
{
//if Dictionary contains given intgr return whole string in which that integer is present
}
}
With LINQ syntax:
var matchingThreads = from pair in dictionary
where pair.Key.StartsWith(number.ToString())
select pair.Value;
With traditional syntax:
var matchingThreads = dictionary
.Where(pair => pair.Key.StartsWith(number.ToString()))
.Select(pair => pair.Value);
If you only need to count them and you don't care about the Thread objects, you can use:
int count = dictionary.Keys.Count(key => key.StartsWith(number.ToString()))
Note that you need a using System.Linq directive.
Maybe a List<CustomClass> would be a better choice here where CustomClass would look like:
public sealed class CustomClass
{
public Thread Thread { get; set; }
public string String { get; set; }
}
(Better property names are alway good, of course :-) )
A dictionary is not sutitable if you do not know the exact keys or only parts of them.
You could then use LINQ to find out what you want, e.g.:
int count = list.Where(c => c.String.StartsWith(integer.ToString())).Count();
//or
IEnumerable<string> strings = list.Where(c => c.String.StartsWith(integer.ToString())).Select(c => c.String);
public IEnumerable<string> GetMatchingKeys(int value)
{
var valueText = value.ToString();
return _dictionary.Keys.Where(key => key.Contains(valueText));
}