0

我正在尝试将用户的电影评分存储在字典中。从中获取数据的文件的格式为

用户名 | 电影ID | 评级 | 时间戳

它们是制表符分隔值

        //Take the first 100 lines from the file and store each line as a array element of text 
        string[] text = System.IO.File.ReadLines(@File path).Take(100).ToArray();

        //extDic[username] - [moviename][rating] is the structure

        Dictionary<string,Dictionary<string,double>> extDic=new Dictionary<string,Dictionary<string,double>>();
        Dictionary<string, double> movie=new Dictionary<string,double>();
        foreach(string s in text)
        {
            int rating;
            string username=s.Split('\t')[0];
            string moviename=s.Split('\t')[1];
            Int32.TryParse(s.Split('\t')[2], out rating);
            movie.Add(moviename,rating);
            if (extDic.ContainsKey(username))
            {   
                //Error line
                extDic[username].Add(moviename, rating);
            }
            else
            {
                extDic.Add(username, movie);
            }
            movie.Clear();
        }

我在错误行上收到以下错误“已添加具有相同密钥的项目”。我了解错误是什么,并尝试通过检查 if 语句来解决它。然而,这并不能解决它。

另外,我想知道是否有重要的movie.clear()?

4

3 回答 3

3

必须有该用户和电影的副本。

要修复错误,您可以将其用于“错误行”:

extDic[username][moviename] = rating;

尽管可能还有其他问题正在发生。

于 2013-11-04T07:39:55.280 回答
1

问题可能是由于您将变量movie用作extDic字典中所有条目的值。movie只是一个参考,所以当你做 a 时,movie.Clear()你正在清除extDic.

您可以完全删除该变量movie并将其替换为new Dictionary<string, double>()

string[] text = System.IO.File.ReadLines(@File path).Take(100).ToArray();

//extDic[username] - [moviename][rating] is the structure

Dictionary<string,Dictionary<string,double>> extDic=new Dictionary<string,Dictionary<string,double>>();   
foreach(string s in text)
{
  int rating;
   //split only once
   string[] splitted = s.Split('\t');

  //UPDATE: skip the current line if the structure is not ok
  if(splitted.Length != 3){
      continue;
  }

  string username=splitted[0];
  string moviename=splitted[1];
  Int32.TryParse(splitted[2], out rating);

  //UPDATE: skip the current line if the user name or movie name is not valid
  if(string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(moviename)){
      continue;
  }


   if(!extDic.ContainsKey(username)){
      //create a new Dictionary for every new user
      extDic.Add(username, new Dictionary<string,double>());
   }
   //at this point we are sure to have all the keys set up
   //let's assign the movie rating
   extDic[username][moviename] = rating;

}
于 2013-11-04T08:04:40.387 回答
1

您的问题是您正在向所有用户添加相同的字典,因此当两个用户对同一部电影进行评分时,您将看到此异常

int rating;
var result  = from line in text
              let tokens = s.Split('\t')
              let username=tokens[0];
              let moviename=tokens[1];
              where Int32.TryParse(tokens[2], out rating);
              group new {username, Rating=new{moviename,rating}} by username;

上面的代码将为您提供一个从树的角度来看与您自己的结构相似的结构。如果您需要查找功能,您可以简单地调用.ToDictionary

var extDic = result.ToDictionary(x=x.Key, x=>x.ToDictonary(y=>y.moviename,y=>y.rating))

我将它重写为 LINQ 的原因是,使用像 LINQ 这样无副作用的东西很难犯这些错误

于 2013-11-04T08:12:44.263 回答