简体   繁体   English

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

[英]How to select/remove elements from a Dictionary<string, List<string>> based on some criteria

I am trying to remove elements from a Dictionary<string, List<string>> in C# when the count of the list<string> is lesser than or equal to 1. I got some code working but it is not elegant and I have a gut feeling that this can be done elegantly in linq. list<string>的计数小于或等于1时,我试图从C#中的Dictionary<string, List<string>>中删除元素。我得到了一些代码,但它不优雅,我有一个直觉感觉这可以在linq中优雅地完成。

This is the code I have now 这是我现在的代码

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

Below is how far I got using linq but this ain't working. 以下是我使用linq的程度,但这不起作用。

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

To put the problem in context I am trying to find anagrams from a dictionary, I consider a words as having anagrams if the sorted key has more than one value associated with it. 为了将问题放在上下文中我试图从字典中找到字谜,如果排序的键具有多个与之关联的 ,我认为单词具有字谜。

You can indeed do this with LINQ: 您确实可以使用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());
}

How it works: 这个怎么运作:

  • Group the words by their letters rearranged in sorted order. 按照按排序顺序重新排列的字母对单词进行分组。
  • Select only the groups which have at least two words. 仅选择至少包含两个单词的组。
  • Convert the result to a dictionary. 将结果转换为字典。
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; });

This uses non-query form linq, and is built up programatically. 这使用非查询形式linq,并以编程方式构建。

  • The Where Selects all key/value pairs in the dictionary where the list has more than one item. Where选择字典中列表包含多个项目的所有键/值对。
  • The Select I removed because it's actually not needed anymore. Select I已删除,因为它实际上不再需要了。 :) :)
  • The Aggregate collects the pairs and performs an add for each item (adding it into the list). 聚合收集对并为每个项目执行添加(将其添加到列表中)。 You could also use .ToDictionary(...) here. 你也可以在这里使用.ToDictionary(...)

If you need to sort your sub-lists change item.Value to item.Value.Sort(s => s).ToList() 如果需要对子列表进行排序,请将item.Value更改为item.Value.Sort(s => s).ToList()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM