多个列表存储到Dictionary <string,list <string =“”>&gt; </string,>

时间:2013-07-26 00:54:46

标签: c# dictionary

我正在尝试将一个英语词典(在这个特定词典中约有109,000个单词)存储到词典&gt;数据结构,我很难搞清楚如何做到这一点。我目前的方法是将单词的第一个字符存储为键值,然后将单词存储在列表中(“wordlist”)。当密钥从'a'变为'b'时,(或'b'变为'c'等)是我被卡住的地方,因为我无法弄清楚如何处理该列表。这是我在这一点上的努力。任何帮助都非常感谢。

public Dictionary<char, IEnumerable<string>> populateWordDictionary()
    {
        Dictionary<char, IEnumerable<string>> wordDictionary = new Dictionary<char, IEnumerable<string>>();
        //List<string> wordList;
        connect = new SqlConnection(connectionString);
        SqlCommand find = new SqlCommand("Select * FROM English order by Word", connect);

        // starting with first record, store each word into the List<string> wordlist
        SqlDataReader dr = null;
        try
        {
            connect.Open();
            dr = find.ExecuteReader();
            char key;
            char keyStartingPosition = 'a';
            List<string> wordList = new List<string>();
            while (dr.Read())
            {
                // if a word is present
                if (!dr.IsDBNull(0))
                {
                    // set Dictionary key value to the first letter in the word being evaluated
                    key = Convert.ToChar(dr[1].ToString().Substring(0, 1));

                    // if the key value is not the same as the starting position, clear the list
                    // i.e., we've advanced to the next letter in the alphabet
                    if (key != keyStartingPosition)
                    {   
                        // add the current list to the dictionary
                        wordDictionary.Add(key, wordList);
                        // advance key starting position to the new key value
                        keyStartingPosition = key;
                        // and clear current content of wordList
                        wordList.Clear();
                    }

                    // if the first letter of the word list hasn't advanced in the alphebet
                    // simply store the word to the current list.
                    if (key == keyStartingPosition)
                    {
                        wordList.Add(dr[1].ToString());
                    }
                }
            }
        }
        catch (Exception ex)
        {

        }
        finally
        {
            connect.Close();
        }

        return wordDictionary;

    }

2 个答案:

答案 0 :(得分:1)

您的一般方法很好,除了wordList.Clear()部分:您继续重复使用相同的列表,并将其副本插入所有键。结果,所有键最终都得到与最后一个键相同的单词列表。

要解决此问题,请将wordList.Clear()替换为

wordList = new List<string>();

并将该行移到wordDictionary.Add行之前:

if (key != keyStartingPosition)
{   
    wordList = new List<string>();
    // add the current list to the dictionary
    wordDictionary.Add(key, wordList);
    // advance key starting position to the new key value
    keyStartingPosition = key;
}

另请注意,由于添加是在遇到给定字母中的第一个字时发生的,因此您需要将keyStartingPosition = 'a'替换为keyStartingPosition = '@'或另一个无法启动真实字词的字母。

答案 1 :(得分:0)

使用LINQ可以更简单地完成:

...
SqlCommand find = ...
var words = this.ToEnumerable(find);
// returns ILookup<char, string>
var wordDictionary = words.ToLookup(w => w[0]);
// wordDictionary['a'] gives an IEnumerable<string> for the words starting with a

// if you really want to use a dictionary, do:
var wordDictionary = works.GroupBy(w => w[0])
    .ToDictionary(g => g.Key, g => g.ToList());

// the ToEnumerable implementation
private IEnumerable<string> ToEnumerable(SqlCommand find)
{
    using (var reader = find.ExecuteReader) {
        while (reader.Read()) {
           if (!reader.IsDBNull(0)) { yield return reader[1].ToString(); }
        }
    }
}