我正在尝试将用户的电影评分存储在字典中。获取数据的文件格式为
UserID | MovieID |评级|时间戳
它们是制表符分隔值
//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()?
答案 0 :(得分:3)
必须有该用户和电影的重复。
要修复错误,您可以将其用于“错误行”:
extDic[username][moviename] = rating;
虽然可能还有其他问题。
答案 1 :(得分:1)
问题可能是因为您使用变量movie
作为extDic
字典中所有条目的值。 movie
只是一个参考,因此当您执行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;
}
答案 2 :(得分: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
这样的副作用来解决这些错误是很困难的。