Как выбрать / удалить элементы из словаря <string, List <string>> на основе некоторых критериев - PullRequest
1 голос
/ 01 сентября 2010

Я пытаюсь удалить элементы из Dictionary<string, List<string>> в C #, когда счетчик list<string> меньше или равен 1. Я получил некоторый работающий код, но он не изящен, и у меня есть ощущение, что этоможно сделать элегантно в Linq.

Это код, который у меня сейчас есть

        Dictionary<string,List<string>> FindAnagrams(List<string> dictionary)
        {
            Dictionary<string, List<string>> anagrams = new Dictionary<string, List<string>>();
            foreach (string word in dictionary)
            {
                char[] charArray=word.ToCharArray();
                Array.Sort(charArray);
                string sorted=new string(charArray);
                if (anagrams.ContainsKey(sorted))
                    anagrams[sorted].Add(word);
                else
                    anagrams.Add(sorted, new List<string>() { word });
            }
            List<string> nonAnagrams = new List<string>();
            foreach (var sorted in anagrams.Keys)
                if (anagrams[sorted].Count == 1)
                    nonAnagrams.Add(sorted);
            foreach(string word in nonAnagrams)
                anagrams.Remove(word);               
            return anagrams;
        }

Ниже показано, как далеко я ушел с помощью linq, но это не работает.

var realAna = from keys in anagrams.Keys
              where anagrams[keys].Count >1
              select anagrams.values;

Чтобы поставить проблемув контексте я пытаюсь найти анаграммы из словаря, я считаю слова имеющими анаграммы, если отсортированный ключ имеет более одного значения , связанного с ним.

Ответы [ 2 ]

2 голосов
/ 01 сентября 2010
var anagrams = new Dictionary<string, IList<string>>()
{
 {"hello", new List<string>(){"hello", "helol", "hlelo"}},
 {"hi", new List<string>(){"hi"}},
 {"me", new List<string>(){"me", "em"}}
};

var a2 = anagrams
 .Where(x => x.Value.Count > 1)
 .Aggregate(new Dictionary<string, IList<string>>(),
  (acc, item) => { acc.Add(item.Key, item.Value); return acc; });

Используется не-запросная форма linq, и она создается программно.

  • Где Выбирает все пары ключ / значение в словаре, где список содержит более одного элемента.
  • Select Я удалил, потому что он больше не нужен. :)
  • Aggregate собирает пары и выполняет добавление для каждого элемента (добавление его в список). Вы также можете использовать .ToDictionary(...) здесь.

Если вам нужно отсортировать подсписки, измените item.Value на item.Value.Sort(s => s).ToList()

2 голосов
/ 01 сентября 2010

Вы действительно можете сделать это с помощью LINQ:

Dictionary<string, List<string>> FindAnagrams(List<string> dictionary)
{
    return dictionary
        .GroupBy(w => new string(((IEnumerable<char>)w).OrderBy(c => c).ToArray()))
        .Where(g => g.Count() > 1)
        .ToDictionary(g => g.Key, g => g.ToList());
}

Как это работает:

  • Группировать слова по их буквам, переставляя их в отсортированном порядке.
  • Выберите только те группы, которые содержат как минимум два слова.
  • Преобразование результата в словарь.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...