Использование строки [] в качестве ключа словаря, например Словарь <string [], StringBuilder> - PullRequest
1 голос
/ 30 марта 2010

Структура, которую я пытаюсь достичь, - это составной словарь, который представляет собой имя элемента и отображаемое имя элемента, а значение словаря представляет собой комбинацию из n строк

Итак, я придумал

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;
        ...
    }
}

Часть, с которой у меня возникают проблемы, - это доступ к словарному ключу pages["KEY"]

Как мне нацелить Ключ словаря, значение которого на [0] == какое-то значение?

Надеюсь, что имеет смысл

Ответы [ 3 ]

2 голосов
/ 31 марта 2010

Основано на комментариях:

Джульетта: Мне кажется, что ты злоупотребляя словарем. Почему ты нужна строка [] в качестве ключа? какой неправильно с использованием "еды и питья" в качестве ключ?

ОП: Я создаю набор вложенных страницы в CMS, перебирая страницы словаря "Еда и напитки" часть будет использоваться в качестве отображаемого имени для страницы в качестве CMS (Sitecore) не позволяет определенные символы в Имена предметов В противном случае при создании страницы, которые я должен был бы сделать, если страница имя == х отображаемое имя = у, которое я не хочу делать

У вас архитектурная проблема, и ключ с массивом строк - определенно неправильный способ ее решения. Никогда не используйте string[] или object[] для специальных групп данных, вместо этого создайте класс.

Кроме того, если ваш словарь основан на одном фрагменте данных, то включите его в один фрагмент данных. Все остальные части данных должны храниться в вашем значении.

Итак, начнем с этого:

public class Page
{
    public readonly string PageTitle;
    public readonly StringBuilder Content;

    public Page(string pageTitle)
    {
        this.PageTitle = pageTitle;
        this.Content = new StringBuilder();
    }
}

И используйте это так:

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);
}

Скорее всего, это не идеальный подход к тому, что вы на самом деле пытаетесь сделать, но я думаю, что это шаг вперед от странности хранения составных данных в качестве ключа словаря. *

2 голосов
/ 30 марта 2010

Это не сработает. Массивы сравнивают равенство по ссылке, а не по содержанию.

Вы должны создать свою собственную вспомогательную структуру, которая имеет как строки, так и Equals() и GetHashCode(), чтобы использовать первую строку, и, возможно, даже имеет неявный оператор преобразования из строки, или предоставить пользовательский IEqualityComparer<string[]> словарь, который выполняет работу по сравнению ключей.

Редактировать - Пример кода:

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;
    }
}
0 голосов
/ 30 марта 2010

Я бы создал новый метод расширения для строки [], чтобы он возвращал хэш содержимого массива, который затем мог бы использоваться в качестве ключа:

    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();
    }

Использование:

var pages = new Dictionary<int, StringBuilder>();
var array = new string[] { "food-and-drink", "Food & Drink" };
pages.Add(array.GetKey(), new StringBuilder());
...