如何从Dictionary <string,list <string =“”>&gt;中选择/删除元素基于一些标准</string,>

时间:2010-09-01 19:18:21

标签: c# linq string refactoring

Dictionary<string, List<string>>的计数小于或等于1时,我试图从C#中的list<string>中删除元素。 我得到了一些代码,但它并不优雅,我有一种直觉,认为这可以在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 个答案:

答案 0 :(得分:2)

您确实可以使用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());
}

工作原理:

  • 按照按排序顺序重新排列的字母对单词进行分组。
  • 仅选择至少包含两个单词的组。
  • 将结果转换为字典。

答案 1 :(得分:2)

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,并以编程方式构建。

  • 其中选择字典中列表包含多个项目的所有键/值对。
  • 我删除了选择,因为实际上不再需要它了。 :)
  • 聚合收集对并为每个项目执行添加(将其添加到列表中)。你也可以在这里使用.ToDictionary(...)

如果您需要对子列表进行排序,请将item.Value更改为item.Value.Sort(s => s).ToList()