我想计算集合中列表中的差异(或相似性)的数量。以下代码是for循环,它产生正确的结果,将每个其他记录与第一个记录进行比较。 有没有办法做得更好?有了Linq,也许?
public void Main(){
_records = new ObservableCollection<Record>();
_records.Add(new Record { Name = "Correct", Results = new List<string> { "A", "B","C" } , Score="100%"} );
_records.Add(new Record { Name = "John", Results = new List<string> { "A", "B" ,"C" } } ); //Expect score to be 3/3 (100%)
_records.Add(new Record { Name = "Joseph", Results = new List<string> { "A", "C","B" } }); //Expect score to be 2/3 (67%)
_records.Add(new Record { Name = "James", Results = new List<string> { "C", "C", "C" } }); //Expect score to be 1/3 (33%)
for(int i = 1; i < _records.Count(); i++) // Each Results in the _records except "Correct"
{
float score = _records[0].Results.Count();
_records[i].Score = string.Format("{0:p1}", (score - CountDifferences(_records[i].Results, _records[0].Results) ) / score );
}
}
private int CountDifferences(List<string> x, List<string> y)
{
return (x.Zip(y, (a, b) => a.Equals(b) ? 0 : 1).Sum());
}
答案 0 :(得分:1)
我会这样做:
var results =
from r0 in _records.Take(1)
from r in _records
let score = (double)r0.Results.Count()
let differences = CountDifferences(r.Results, r0.Results)
select new { record = r, score = ((score - differences) / score).ToString("p1") };
foreach (var result in results)
{
result.record.Score = result.score;
}
我愿意,hovever建议您没有.Score
作为Record
的属性,因为只有当您可以将一条记录与另一条记录进行比较时,分数才有效。这意味着如果您有三个单独的结果,如果您与其他两个中的任何一个进行比较,那么得分可能会有所不同。
所以我会建议:
public class Record
{
public string Name;
public List<string> Results;
public double GetScore(Record benchmark)
{
var max = benchmark.Results.Count;
var differences = benchmark.Results
.Zip(this.Results, (a, b) => a == b)
.Where(r => r == false)
.Count();
return ((double)max - differences) / max;
}
}
然后只需执行此查询即可获得结果:
var results =
from r0 in _records.Take(1)
from r in _records
select new
{
record = r,
score = r.GetScore(r0).ToString("p1")
};
这让我:
答案 1 :(得分:-1)
我将LINQ(带有lambda表达式)语句用于使用学生名称作为键和自定义类Record作为值的字典。然后将其与单独的列表进行比较,预期成绩。
List<string> expected = new List<string>(){"A", "B","C" };
Dictionary<string, Record> _records = new Dictionary<string, Record>();
_records["John"] = new Record { Name = "John", Results = new List<string> { "A", "B" ,"C" } } ;
_records["Joseph"]= new Record { Name = "Joseph", Results = new List<string> { "A", "C","B" } } ;
_records["James"] = new Record { Name = "James", Results = new List<string> { "C", "C", "C" } } ;
foreach(var v in _records){
decimal count = v.Value.Results.Where((x,index) => expected[index]==x).Count()/(decimal)expected.Count();
v.Value.Score = String.Format("{0:P0}",count);
}
foreach(var v in _records)
Console.WriteLine("{0} {1}",v.Value.Name,v.Value.Score);