Что не так с этим кодом C#
Я пытаюсь создать инвертированный индекс, но он не работает. мои коды не содержат ошибок, но не работают. что с этим не так?
Я получаю это исключение каждый раз: KeyNotFoundException was unhandled : the given Key was not present in the dictionary
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static Dictionary<TItem, IEnumerable<TKey>> Invert<TKey, TItem>(Dictionary<TKey, IEnumerable<TItem>> dictionary)
{
return dictionary
.SelectMany(keyValuePair => keyValuePair.Value.Select(item => new KeyValuePair<TItem, TKey>(item, keyValuePair.Key)))
.GroupBy(keyValuePair => keyValuePair.Key)
.ToDictionary(group => group.Key, group => group.Select(keyValuePair => keyValuePair.Value));
}
static void Main(string[] args)
{
Console.WriteLine("files: ");
//read all the text document on the specified directory; change this directory based on your machine
foreach (string file in Directory.EnumerateFiles("D:\\IR\\", "*.txt"))
{
string contents = File.ReadAllText(file);
Console.WriteLine(contents);
Console.Write("find: ");
var find = Console.ReadLine();
var dictionary = file.Split().ToDictionary(files => files, files => File.ReadAllText(file).Split().AsEnumerable());
Console.WriteLine("{0} found in: {1}", find, string.Join(" ", Invert(dictionary)[find]));
}
}
}
}
Я отредактировал коды и теперь он работает без ошибок и исключений. теперь есть еще одна проблема: он должен иметь возможность читать все файлы только один раз, но я не могу иметь в виду это каждый раз, когда читаю один из них и затем выполняю процесс поиска, и это не моя точка зрения, мне нужен вывод, подобный тому, что я написал ниже. Кажется, я должен изменитьforeach(string file in Dictionary.EnumerateFiles("D:\\IR\\","*.txt"))
к чему-то еще. но я не знаю что это.
вывод должен быть таким:
файлы: файл1 файл2 файл3
найти то, что
что найдено в: file1 file2
1 ответ
Изменить: я проверил вашу версию Invert
и это, кажется, работает просто отлично. Вы запутались по умолчанию ToString()
выход? Если вы пытаетесь напрямую печатать Program.Invert(dictionary)[find]
, вы не получите ожидаемый результат, так как по умолчанию ToString()
не очень полезно (из-за того, что объект, который вы пытаетесь распечатать, не переопределяет object.ToString()
). Вам придется перебирать свой список значений и печатать каждое из них по отдельности. Если предположить, TKey
Переопределение ToString()
, вы получите желаемый результат. Например,
Console.WriteLine("{0} found in: ", find);
foreach (var val in Program.Invert(dictionary)[find])
{
Console.WriteLine(val);
}
Предыдущий ответ (сохранен для потомков): Хорошо, вы упомянули, что что-то не так в вашем Invert
метод. Я пытался написать Invert
мой собственный метод и вот что я придумала. Я разбил вызовы методов на отдельные части, чтобы было ясно, что я делаю.
static Dictionary<TItem, IEnumerable<TKey>> Invert<TKey, TItem>(Dictionary<TKey, IEnumerable<TItem>> dictionary)
{
// Get collection of all the values which will be keys in the new inverted dictionary
var invertedDictKeys = dictionary.SelectMany(keyValPair => keyValPair.Value).Distinct();
// Perform the invert
var invertedDict =
invertedDictKeys.Select(
invertedKey =>
new KeyValuePair<TItem, IEnumerable<TKey>>(invertedKey, dictionary.Keys.Where(key => dict[key].Contains(invertedKey))));
// Convert to dictionary and return
return invertedDict.ToDictionary(keyValPair => keyValPair.Key, keyValPair => keyValPair.Value);
}