Using string[] as a Dictionary key e.g. Dictionary<string[], StringBuilder>
The structure I am trying to achieve is a composite Dictionary key which is item name and item displayname and the Dictionary value being the combination of n string开发者_开发百科s
So I came up with
var pages = new Dictionary<string[], StringBuilder>()
{
{ new string[] { "food-and-drink", "Food & Drink" }, new StringBuilder() },
{ new string[] { "activities-and-entertainment", "Activities & Entertainment" }, new StringBuilder() }
};
foreach (var obj in my collection)
{
switch (obj.Page)
{
case "Food":
case "Drink":
pages["KEY"].Append("obj.PageValue");
break;
...
}
}
The part I am having trouble with is accessing the Dictionary Key pages["KEY"]
How do I target the Dictionary Key whose value at [0] == some value?
Hope that makes sense
Based on some comments:
Juliet: It sounds to me like you're abusing the dictionary. Why do you need a string[] as a key? What's wrong with using "food-and-drink" as a key?
OP: I am creating a set of nested pages in the CMS by looping over the pages Dictionary, the "Food & Drink" part would be used as the display name for the page as the CMS (Sitecore) doesn't allow certain characters in the items name Otherwise when creating the pages I would have to do if page name == x display name = y, which I don't want to do
You have an architectural problem, and a key with a string array is definitely the wrong way to solve it. Never use a string[]
or object[]
for ad hoc groups of data, create a class instead.
Additionally, if your dictionary is keyed on one piece of data, then make it keyed on one piece of data. All other data parts should be stored in your value.
So let's start with this:
public class Page
{
public readonly string PageTitle;
public readonly StringBuilder Content;
public Page(string pageTitle)
{
this.PageTitle = pageTitle;
this.Content = new StringBuilder();
}
}
And use it like this:
var pages = new Dictionary<string, Page>()
{
{ "food-and-drink", new Page("Food & Drink") },
{ "activities-and-entertainment", new Page("Activities & Entertainment")
};
foreach (var obj in myCollection)
{
pages[obj.Page].Content.Append(obj.PageValue);
}
Odds are, this isn't the perfect approach for what you're actually trying to do, but I think its a step up from the weirdness of storing composite data as a dictionary key.
This won't work. Arrays compare equality by their reference, not their content.
You have to create your own helper structure which has both strings and overrides both Equals()
and GetHashCode()
to use the first string and maybe even has an implicit conversion operator from string, or supply a custom IEqualityComparer<string[]>
to the dictionary which does the work of comparing the keys.
Edit - Code Sample:
public struct MyKey: IEquatable<MyKey> {
public static implicit operator MyKey(string key) {
return new MyKey(key, key);
}
private readonly string key;
private readonly string display;
public MyKey(string key, string display) {
this.key = key;
this.display = display;
}
public override bool Equals(object other) {
if (other is MyKey) {
return Equals((MyKey)other);
}
return false;
}
public bool Equals(MyKey other) {
return other.key == key;
}
public override int GetHashCode() {
if (key != null) {
return key.GetHashCode();
}
return 0;
}
public string Key {
get {
return key;
}
}
public override string ToString() {
return display ?? string.Empty;
}
}
I would create a new extension method on string[] to return a hash of the contents of the array that could then be used as a key:
public static int GetKey(this string[] array)
{
var builder = new System.Text.StringBuilder();
foreach (var value in array)
{
builder.Append(value);
}
return builder.ToString().GetHashCode();
}
Use:
var pages = new Dictionary<int, StringBuilder>();
var array = new string[] { "food-and-drink", "Food & Drink" };
pages.Add(array.GetKey(), new StringBuilder());
精彩评论