Domanda

I try to create an inverted index but it doesn't work. my codes have no error but doesn't work. what's wrong with it?

I get this exception every time : 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]));
            }
         }
     }
}

I edited the codes and now it work without error and exception. now there is another problem it must be able to read all of files only once but it can't I mean it every time read one of them and then do Finding process and it's not my point I need an output like what I wrote bellow. It seems I should changeforeach(string file in Dictionary.EnumerateFiles("D:\\IR\\","*.txt")) to something else. but I don't know what it is.

output should be like this :

files: file1 file2 file3

find: what

what found in: file1 file2

È stato utile?

Soluzione

Edit: I tested your version of Invert and that seems to work just fine. Are you getting confused by the default ToString() output? If you directly try to print Program.Invert(dictionary)[find], you will not get the output you expect since the default ToString() is not very helpful (due to the fact that the object you are trying to print does not override object.ToString()). You will have to iterate through your list of values and individually print each one. Assuming TKey overrides ToString(), you will get the output you want. For example,

Console.WriteLine("{0} found in: ", find);
foreach (var val in Program.Invert(dictionary)[find])
{
    Console.WriteLine(val);
}

Previous Answer (saved for posterity): Alright, you mentioned that something is wrong in your Invert method. I tried to write up an Invert method of my own and here's what I came up with. I've broken up the method calls in to separate parts so that it's clear what I'm doing.

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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top