3

読むために私はこのコードを試しました:

Form1の上部で私はしました:

Dictionary<string, List<string>> LocalyKeyWords = new Dictionary<string, List<string>>();

コンストラクターで私はしました:

keywords = @"d:\Keywords.txt";
            if (File.Exists(keywords))
            {
                LoadKeys(LocalyKeyWords, keywords);
            }

関数LoadKeys:

private void LoadKeys(Dictionary<string,List<string>> disctionary, string FileName)
        {
            var lines = File.ReadAllLines(keywords).Select(l => l.Split(','));
            var dict = new Dictionary<string, List<string>>();
            foreach(var splits in lines)
            {
                var key = splits.First();
                var value = splits.Skip(1).ToList();
                try {dict.Add(key, value);
                }
                catch(Exception ex)
                {  } } 
        }

例外はありませんが、関数を呼び出してすべてが実行された後のコンストラクターでは、LocalyKeyWordsは空です。


これは、今日のファイルへのキーと値の書き込み方法です。

private void button6_Click(object sender, EventArgs e)
        {

            using (var w = new StreamWriter(keywords))
            {
                crawlLocaly1 = new CrawlLocaly();
                crawlLocaly1.StartPosition = FormStartPosition.CenterParent;
                DialogResult dr = crawlLocaly1.ShowDialog(this);
                if (dr == DialogResult.OK)
                {
                    if (LocalyKeyWords.ContainsKey(mainUrl))
                    {
                        LocalyKeyWords[mainUrl].Clear();
                        LocalyKeyWords[mainUrl].Add(crawlLocaly1.getText());
                    }
                    else
                    {
                        LocalyKeyWords[mainUrl] = new List<string>();
                        LocalyKeyWords[mainUrl].Add(crawlLocaly1.getText());
                    }
                    foreach (KeyValuePair<string, List<string>> kvp in LocalyKeyWords)
                    {
                        w.WriteLine(kvp.Key + "," + string.Join(",", kvp.Value));
                    }
                }
            } 
        }

コンストラクターでのキーと値のロードを解決し、button6clickイベントでキーまたは値を変更するたびに書き込む方法の問題を解決できるようになるかもしれません。

4

6 に答える 6

3
var lines = File.ReadAllLines("path/to/file").Select(l => l.Split(','));
var dict = new Dictionary<string, List<string>();
foreach(var splits in lines) 
{
    var key = splits.First();
    var value = splits.Skip(1).ToList();
    try {dict.Add(key, value);}
    catch(Exception ex) { //TODO: handle }
}
return dict;
于 2012-10-11T16:57:38.090 に答える
2

非常に大きなファイルがある場合は、実行を延期し、すべての行をメモリにロードせず、すべての行をメモリにロードするときにあまり最適化されていない、 ではなくReadLinesを使用することを強くお勧めします。ReadAllLinesReadLinesReadAllLines

var result = File.ReadLines("text.txt")
                 .Select(line => line.Split(','))
                 .ToDictionary(x => x.First(),
                               x => x.Skip(1).ToList());

同じキーを使用している場合は、Dictionary適切なオプションではありません。代わりに、次を使用できます。

var result = File.ReadLines("text.txt")
            .Select(line => line.Split(','))
            .Select(x => new KeyValuePair<string, List<string>>(x.First(), x.Skip(1).ToList()));
于 2012-10-11T17:00:56.563 に答える
2

上記の提案に基づいて、これにより重複するキーがグループ化され、それぞれに固有の値が提供されます。

           // Turn the file into an Enumerable of lines
var dict = File.ReadLines("path/to/file")
           // For each line, turn it into an array of comma-separated values
           .Select(line => line.Split(','))
           // Group the lines together by their first token (the key)
           // The values of the groupings will be the "tokenized" lines
           .GroupBy(line => line[0])
           // Create a dictionary from the collection of lines, 
           // using the Key from the grouping (the first token)
           .ToDictionary(group => group.Key,
                         // Set the values of each entry to the arrays
                         // of tokens found for each key (merging 
                         // them together if a key was found multiple times)
                         group => group.SelectMany(values => 
                                  // ...ignoring the first token and filtering
                                  // out duplicate values
                                  values.Skip(1).Distinct().ToList()));
return dict;

たとえば、次のテキストを含むファイル:

1,a,b,c
1,c,d,e
2,e,f,g

次の辞書に変換されます。

1 : {a,b,c,d,e}
2 : {e,f,g}

@Vladが指摘しているように、ファイルはディクショナリから生成され、重複が含まれていてはならないため、重複を除外する必要はありません。 ファイルに重複がある理由を突き止め、その問題を修正することを強くお勧めします。 次に、ファイルを辞書にロードする関数を大幅に簡略化して、グループ化とDistinct呼び出しを削除し、次のようにすることができます。

var dict = File.ReadLines("path/to/file")
           // For each line, turn it into an array of comma-separated values
           .Select(line => line.Split(','))
           // Create a dictionary from the collection of lines, 
           // using the the first token as the key
           .ToDictionary(tokens => tokens[0],
                         // Set the value of each entry to the a
                         // list containing each token on that line
                         // (after the first, which is the key)
                         tokens => tokens.Skip(1).ToList());
return dict;
于 2012-10-11T17:24:57.853 に答える
1

ええと、基本的に読むためには、書くこととは逆のことをします。

ファイル()を開き、 1行ずつ(またはさらに適切var w = new StreamReader(keywords)に)読み取り、各行を解析します。while (w.Peek() >= 0) { var l = sr.ReadLine()); ...string l; while ((l = sr.ReadLine()) != null) { ...

行を解析するstring.Splitために、それをコンマで分割するために使用できるので、キーはパーツのリストの0番目のエントリであり、残りは値です。

編集:Peek@Jonのおかげで、なしで代替ソリューションを追加しました。

于 2012-10-11T16:58:21.240 に答える
1
string line = System.String.Empty;
using (StreamReader sr = new StreamReader("MyFile.txt")
{
    while ((line = sr.ReadLine()) != null)
    {
         string[] tokens = line.Split(',');    
         LocalKeyWords.Add(tokesn[0], tokens[1]);
    }
}

おそらくそれをtrycatchでラップする必要があります。

于 2012-10-11T16:59:02.673 に答える
1

コード:

var delimiter = new[] {','};

var splits = File.ReadLines("text.txt")
                 .Where(line => !string.IsNullOrWhiteSpace(line))
                 .Select(line => line.Split(delimiter));
                 // Add "StringSplitOptions.RemoveEmptyEntries" if you want
                 // Add ".Where(split => split.Length > 1)" to exclude empty keys

var lookup = splits.ToLookup(split => split[0], split => split.Skip(1));
var dict = lookup.ToDictionary(x => x.Key, x => x.SelectMany(s => s).ToList());

デバッグに適していませんが、行は少なくなります。

var dict = File.ReadLines("text.txt")
               .Where(line => !string.IsNullOrWhiteSpace(line))
               .Select(line => line.Split(delimiter))
               .ToLookup(split => split[0], split => split.Skip(1))
               .ToDictionary(x => x.Key, x => x.SelectMany(s => s).ToList());

入力例:

1、a、b、c

2、a、b、c

1、a、e、d

3

2、a

4、a、b

出力:

1:{a、b、c、a、e、d}

2:{a、b、c、a}

3:{}

4:{a、b}

于 2012-10-11T19:49:14.040 に答える