C# Linq计数集合中列表中的差异数

C# Linq计数集合中列表中的差异数,c#,linq,C#,Linq,我想计算集合中列表中的差异(或相似性)数量。 有没有办法做得更好?也许是和林克 public void Main(){ _records = new ObservableCollection<Record>(); _records.Add(new Record { Name = "Correct", Results = new List<string> { "A", "B","C" } , Score="100%"} );

我想计算集合中列表中的差异(或相似性)数量。 有没有办法做得更好?也许是和林克

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());
}
public void Main(){
_记录=新的ObservableCollection();
_添加(新记录{Name=“Correct”,结果=新列表{“A”、“B”、“C”},分数=“100%”);
_Add(新记录{Name=“John”,Results=新列表{“A”、“B”、“C”});//预期分数为3/3(100%)
_添加(新记录{Name=“Joseph”,结果=新列表{“A”、“C”、“B”});//预计分数为2/3(67%)
_添加(新记录{Name=“James”,结果=新列表{“C”,“C”,“C”});//预计分数为1/3(33%)
for(int i=1;i<_records.Count();i++)//除“Correct”外,每个结果都是_记录
{
浮动分数=_记录[0]。结果。计数();
_记录[i].Score=string.Format(“{0:p1}”,(Score-CountDifferences(_记录[i].Results,_记录[0].Results))/Score);
}
}
私有整数计数差异(列表x、列表y)
{
返回(x.Zip(y,(a,b)=>a.Equals(b)?0:1.Sum();
}

我会这样做:

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;
}
我建议您不要将
.Score
作为
记录的属性,因为只有当您可以将一条记录与另一条记录进行比较时,分数才有效。这意味着,如果你有三个不同的结果,如果你与其他两个结果中的任何一个进行比较,分数可能会有所不同

因此,我建议:

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
    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;
}
我建议您不要将
.Score
作为
记录的属性,因为只有当您可以将一条记录与另一条记录进行比较时,分数才有效。这意味着,如果你有三个不同的结果,如果你与其他两个结果中的任何一个进行比较,分数可能会有所不同

因此,我建议:

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;
    }
}
这给了我:

我让LINQ(带lambda表达式)语句在一个字典中工作,该字典使用学生的名字作为键,自定义类记录作为值。然后将其与单独的列表进行比较,得出预期的等级

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);
List expected=newlist(){“A”、“B”、“C”};
字典_记录=新字典();
_记录[“John”]=新记录{Name=“John”,结果=新列表{“A”、“B”、“C”};
_记录[“约瑟夫”]=新记录{Name=“约瑟夫”,结果=新列表{“A”、“C”、“B”};
_记录[“James”]=新记录{Name=“James”,结果=新列表{“C”、“C”、“C”};
foreach(var v in_记录){
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_记录)
WriteLine(“{0}{1}”,v.Value.Name,v.Value.Score);
我让LINQ(带lambda表达式)语句在一个字典中工作,该字典使用学生的名字作为键,自定义类记录作为值。然后将其与单独的列表进行比较,得出预期的等级

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);
List expected=newlist(){“A”、“B”、“C”};
字典_记录=新字典();
_记录[“John”]=新记录{Name=“John”,结果=新列表{“A”、“B”、“C”};
_记录[“约瑟夫”]=新记录{Name=“约瑟夫”,结果=新列表{“A”、“C”、“B”};
_记录[“James”]=新记录{Name=“James”,结果=新列表{“C”、“C”、“C”};
foreach(var v in_记录){
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_记录)
WriteLine(“{0}{1}”,v.Value.Name,v.Value.Score);

为什么你期望第三项记录的分数为67%?我只能假设你的意思是约瑟夫得到了33%的分数;正如神秘所暗示的那样。因为根据索引排列的唯一分数是A。基于这个假设,我给出了一个使用字典而不是自定义类的答案。你为什么期望第三个记录的分数为67%?我只能假设你真的是说Joseph得到了33%的分数;正如神秘所暗示的那样。因为按索引排列的唯一分数是A。基于这个假设,我给出了一个使用字典而不是自定义类的答案。谢谢你的索引功能@沃特林:我想知道为什么这次投票会被否决。除了选择答案之外,你还可以投票给那些能增加价值或帮助你理解事物的答案和评论。这可以是你自己的问题,也可以是你在寻找问题答案时找到的任何解决方案。谢谢,我不是在暗示你这么做。我只是想问你是否可以把它选为答案。谢谢。谢谢你的索引功能@沃特林:我想知道为什么这次投票会被否决。除了选择答案之外,你还可以投票给那些能增加价值或帮助你理解事物的答案和评论。这可以是你自己的问题,也可以是你在寻找问题答案时找到的任何解决方案。谢谢,我不是在暗示你这么做。我只是想问你是否可以把它选为答案。谢谢