2017-02-18 10 views
1

コレクション内のリストの相違点(または類似点)の数をカウントします。次のコードは、正しい結果を生成するforループです。最初のレコード。 良い方法がありますか? Linqと、おそらく?Linq countコレクション内のリストの相違数

私はこのようにそれをやって行くだろう
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

なぜ3番目のレコードのスコアが67%になると思いますか? – Enigmativity

+0

私は、あなたが本当にヨセフが33%の得点を得ていたと仮定することができます。 Enigmativityによって示唆されるように。インデックスで整列する唯一の等級はA.なので、その前提に基づいて、私はあなたのカスタムクラスの代わりに辞書を使う答えを出しました。 – Edward

答えて

-1

を私が作りましたLINQ(ラムダ式付き)ステートメントは、スタッドを使用する辞書を処理します。キーとしてのntsの名前と値としてのカスタムクラスのレコード。その後、成績が期待される別のリストと比較してください。

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); 
+0

そのインデックス機能をお寄せいただきありがとうございます。 – Jean

+0

@ watlingなぜこれにダウン投票があるのだろうか。回答を選択するだけでなく、値を付け加えたり、何かを理解するのに役立つ回答やコメントを上書することもできます。これは、あなた自身の質問や、あなたが持っている問題に対する答えを探す際に見つけるあらゆる解決策になります。ありがとう。 – Edward

+0

私はdownvoteしませんでした。私はこれを受け入れた! @エドワード – Jean

1

:あなたは1を比較することができたときにスコアが唯一の有効なようあなたがRecordのプロパティとして.Scoreを持っていないことを示唆しているhovever私は

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; 
} 

なり、別のものに対して記録する。つまり、3つの別々の結果がある場合は、他の2つのいずれかと比較するとスコアが異なる可能性があります。

だから私はこのことをお勧め:それからちょうど結果を得るために、このクエリを実行

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") 
    }; 

私に与える:

results

関連する問題