I started learning about MVC 6 and I found this tutorial.
The following code is quoted from the linked site:
//TodoItem.cs
namespace TodoApi.Models
{
public class TodoItem
{
public string Key { get; set; }
public string Name { get; set; }
public bool IsComplete { get; set; }
}
}
The TodoItem class will be a value field in a ConcurrentDictionary:
static ConcurrentDictionary<string, TodoItem> _todos =
new ConcurrentDictionary<string, TodoItem>();
The key field which has string type will contain the same value as TodoItem.Key:
public void Add(TodoItem item)
{
item.Key = Guid.NewGuid().ToString();
_todos[item.Key] = item;
}
Does this means that each time a new item is added the the Key will stored twice(once is the key field of the dictionary and once inside the value field) or I am missing something?
I came across this situation in C++ using std::map too and I always used something like this to avoid storing the value of Key two times:
struct Item
{
//std::string Key;
std::string Name;
bool IsComplete;
};
std::map<std::string, Item> items;
// ^^ Item.Key
Does this means that each time a new item is added the the Key will
stored twice(once is the key field of the dictionary and once inside
the value field) or I am missing something?
In .NET System.String type is a reference type, so you shouldn't be worried about the key being stored twice. It will be a single instance in memory to which both the Key of the dictionary and the Key property of the item are simply pointing to. So don't worry about redundancy in this situation. The ConcurrentDictionary structure that you are using here is just a simple wrapper of pointers around your actual data.
Also worth mentioning another interesting property of the System.String type in .NET. Even if you have 2 different instances of a string with the same value the runtime could decide to intern them and they will point to the same data in memory:
string a = "abc";
string b = "abc";
bool res = object.ReferenceEquals(a, b); // true
Related
My code converts a json file in to a dictionary of dictionaries where the value is a class I built.
This is the class:
public class JsonPart
{
public string sql { get; set; }
public string oracle { get; set; }
public List<string> Hebrew { get; set; }
}
This is the dictionary I am converting to:
public static Dictionary<string, Dictionary<string, JsonPart>> j;
I want to check if the dictionary contains a specific key where the value is a dictionary how's key I know and in the value (class JsonPart) under the list named Hebrew there is the word I am looking for.
For example external key is "MandatoryWords", internal key is "select", and the list Hebrew contains the word "בחר".
I need to check the whole path and not just the last word as the dictionary is only built while running and I do not know if it really contains these keys.
Even if I assume these keys exist in the dictionary how do I access them if the dictionary is only built while running?
Not sure if I understand you correctly, but do you mean you are given an external key, an internal key and a word in Hebrew, and you want to check if this combination exists in the dictionary?
Then you could do this:
public static bool Check(string externalKey, string internalKey, string word) {
if (j.TryGetValue(externalKey, out var innerDic))
{
if (innerDic.TryGetValue(internalKey, out var jsonPart))
{
return jsonPart.Hebrew.Contains(word);
}
}
return false;
}
So i need to create a data-structure with one Key, sub Key and Value. And a method to Add Key, sub Key and Value.
The Key are unique and can have multiple Sub Keys.
The Sub Key are uniques in the context inside Key and can have multiple Values.
The Values are unique inside the context of the Sub Key.
The first data-structure that comes to my mind was Dictionary (perform time is important for the task).
Then i created the following dictionary.
public class NewCollection : IHoplonCollection
{
class SubIndexAndValue
{
public int subIndex;
public List<string> Value = new List<string>();
}
class DataStructure : IComparable<DataStructure>
{
public string Key;
public List<SubIndexAndValue> subIndexValue = new List<SubIndexAndValue>();
public int CompareTo(DataStructure other)
{
if (Key.CompareTo(other.Key) > 0)
{
return 1;
}else if (Key.CompareTo(other.Key) < 0)
{
return -1;
}else
{
return 0;
}
}
}
SortedDictionary<DataStructure, SubIndexAndValue> colList = new SortedDictionary<DataStructure, SubIndexAndValue>();
public bool Add(string Key, int subIndex, string Value)
{
return true;
}
So as you can see the Add method will receive the Key, Sub Key and Value.
In the future i will need to do a CRUD and sort data.
My question is, how do i handle this? How can i use method like Contains() to check if one Value (string) was already inserted in the dictionary using this data-structure? Or maybe there is an easyer way to do this.
Thanks.
I think that a combination of built-in structures can solve your proposed datastructure:
Dictionary<string,Dictionary<int,HashSet<string>>>
The first dictionary holds list of key-value pairs of string (Key), and for every one of them, the value it's another Dictionary whose key is a unique string (SubKey) and the value is a HashSet<string>, a list of unique strings.
public class Quote
{
public decimal Price { get; set; }
public string Symbol { get; set; }
}
public List<Quote> quotes =
new List<Quote>(){new Quote{Price=100.00,Symbol="AAPL"},
new Quote{Price=200.00,Symbol="GOOG"}}
List<string,Quote> positions = new List<string,Quote>();
I want to set each position.Key to Quote.Symbol and each position.Value to Quote
What's the best way to convert ?
If i understand what you are asking (and that's a big if), it should be as simple as
var someDictionary = quotes.ToDictionary(x => x.Symbol);
Enumerable.ToDictionary Method
Creates a Dictionary from an IEnumerable.
Also take a look at
Enumerable.ToLookup Method
Creates a generic Lookup from an IEnumerable.
A dictionary is a 1:1 map (each key is mapped to a single value), and a dictionary is mutable (editable) after the fact.
A lookup is a 1:many map (multi-map; each key is mapped to an IEnumerable<> of the values with that key), and there is no mutate on the ILookup<,> interface.
I have an object with some properties and a dictionary which holds a temporary value for each of property. The key of this dictionary is a string with the same name of the property, while the value is an object.
What I want to do is to build a save method that reads the dictionary's keys and set the corresponding property to the value found in the dictionary.
So I thought about reflection but it's not as easy as I thought.
Here's a sample class:
public class Class{
public string Property1 { get; set; }
public int Property2 { get; set; }
public Dictionary<string, object> Settings { get; set; }
public void Save()
{
foreach (string key in Settings.Keys)
{
// PSEUDOCODE
get the property called like the key
get its type
get the value of hte key in the dictionary
cast this object to the property's value
set the property to the casted object
}
}
}
The reason why I'm not posting my code is beacuse I don't understand how to do casting and similar stuff, so I wrote a little bit of pseudocode to let you understand what I'm trying to achieve.
Is there anyone that can point me to the right direction?
Here:
//Get the type
var type= this.GetType();
foreach (string key in Settings.Keys)
{
//Get the property
var property = type.GetProperty(key);
//Convert the value to the property type
var convertedValue = Convert.ChangeType(Settings[key], property.PropertyType);
property.SetValue(this, convertedValue);
}
Not tested, but it should work.
I want to use a KeyedCollection to store a class against a string key value. I have the following code:
public class MyClass
{
public string Key;
public string Test;
}
public class MyCollection : KeyedCollection<string, MyClass>
{
public MyCollection() : base()
{
}
protected override String GetKeyForItem(MyClass cls)
{
return cls.Key;
}
}
class Program
{
static void Main(string[] args)
{
MyCollection col = new MyCollection();
col.Add(new MyClass()); // Here is want to specify the string Key Value
}
}
Can anyone tell me what I’m doing wrong here? Where do I specify the key value so that I can retrieve by it?
Your GetKeyForItem override is what specifies the key for an item. From the docs:
Unlike dictionaries, an element of KeyedCollection is not a key/value pair; instead, the entire element is the value and the key is embedded within the value. For example, an element of a collection derived from KeyedCollection<String,String> might be "John Doe Jr." where the value is "John Doe Jr." and the key is "Doe"; or a collection of employee records containing integer keys could be derived from KeyedCollection<int,Employee>. The abstractGetKeyForItem` method extracts the key from the element.
So in order for the item to be keyed correctly, you should set its Key property before adding it to the collection:
MyCollection col = new MyCollection();
MyClass myClass = new MyClass();
myClass.Key = "This is the key for this object";
col.Add(myClass);
The KeyedCollection is a base class for creating keyed collections, so there is quite a lot that you need to implement yourself.
Perhaps using a Dictionary would be easier and faster to work with.
I know it's slightly different, but have you considered implementing an indexer.
public string this[string index]
{
get {
// put get code here
}
set {
// put set code here.
}
}