Я изучаю C # и пытаюсь сделать что-то простое: ввести несколько тегов, разделенных запятыми, кода для возврата сообщения. Идея состоит в том, что код должен фильтровать все теги, которые я разбиваю на массив.

Определение переменных:

Dictionary<string[], string> messages = new Dictionary<string[], string>();
messages.Add(new string[] { "greeting", "hello", "hei", "hi" }, "Hello!");
messages.Add(new string[] { "greeting", "bye", "buh-bye", "sayonara" }, "Bye!");

Получение тега:

string[] tags;
tags.Add("greeting");
tags.Add("hello");

Список и повторение:

List<string> lista = new List<string>();
foreach(string tag in e.GetArg("Tag").Split(','))
{
    foreach (KeyValuePair<string[], string> entry in gifs)
    {
        if (entry.Key.Contains(tag))
        {
            lista.Add(entry.Value);
        }
    }
}

Проблема заключается в том, что он добавляет каждый встреченный элемент для каждого тега в списке , даже элемент «пока». Могу ли я отфильтровать это с помощью массива тегов? Или мне нужно проходить еще раз, каждый раз получая желаемый (е)?

3
yomisimie 26 Ноя 2016 в 01:11

2 ответа

Лучший ответ

Поиск в словаре по массиву ключей

        Dictionary<string[], string> messages = new Dictionary<string[], string>();
        messages.Add(new string[] { "greeting", "hello", "hei", "hi" }, "Hello!");
        messages.Add(new string[] { "greeting", "bye", "buh-bye", "sayonara" }, "Bye!");

        // add tags
        string[] tags = new string[2];
        tags[0] = "greeting";
        tags[1] = "buh-bye";

        List<string> lista = new List<string>(); // list to store the results

        // loop true the keys from every row
        // loop true the keys of the current row
        // check if tags contains key 
        // ckeck if lista already contains the key that was recognized(no duplicates in list)

        foreach (var value in messages.Keys)
            foreach (var value1 in value)
                if (tags.Contains(value1))
                    if(!lista.Contains(messages[value]))
                        lista.Add(messages[value]);

Выход

      ==========
      lista Count = 2
      1: Hello
      2: Bye!
3
Timon Post 25 Ноя 2016 в 23:29

Думаю, вы можете использовать простой класс для поиска по тегам. Это решение улучшит уровень абстракции вашего кода. Пример класса:

public class TagDictionary
{
    Dictionary<string, HashSet<string>> _innerStorage = new Dictionary<string, HashSet<string>>();

    public void Add(IEnumerable<string> tags, string value)
    {
        foreach (var tag in tags)
        {
            if (_innerStorage.ContainsKey(tag))
            {
                var hash = _innerStorage[tag];
                if (!hash.Contains(value))
                {
                    hash.Add(value);
                }
            }
            else
            {
                _innerStorage[tag] = new HashSet<string>
                {
                    value
                };
            }
        }
    }

    public HashSet<string> GetValuesByTags(IEnumerable<string> tags)
    {
        var result = new HashSet<string>();
        foreach (var tag in tags)
        {
            if (_innerStorage.ContainsKey(tag))
            {
                result.UnionWith(_innerStorage[tag]);
            }
        }
        return result;
    }
}

Пример использования:

    static void Main(string[] args)
    {
        var messages = new TagDictionary();
        messages.Add(new string[] { "greeting", "hello", "hei", "hi" }, "Hello!");
        messages.Add(new string[] { "greeting", "bye", "buh-bye", "sayonara" }, "Bye!");

        foreach (var value in messages.GetValuesByTags(new[] { "greeting", "hello" }))
        {
            Console.WriteLine(value);
        }
    }

Просто string[] не подходит для стандартного ключа Dictionary.

1
Evgeniy Mironov 26 Ноя 2016 в 00:11