Note that there are some explanatory texts on larger screens.

plurals
  1. POProcessing ranking data w/ C# & LINQ
    text
    copied!<p>I have an object in a list that I need to rank several different ways. Currently the code is rather unwieldy as it requires me to individually address each column. Example:</p> <pre><code>public class Data { public int AValue { get; set; } public int ARanking { get; set; } public int BValue { get; set; } public int BRanking { get; set; } public int CValue { get; set; } public int CRanking { get; set; } } public class Container { public List&lt;Data&gt; RankingData { get; set; } public void RankData() { int count = 1; foreach (Data item in RankingData.OrderBy(d =&gt; d.AValue)) { item.ARanking = count; count++; } count = 1; foreach (Data item in RankingData.OrderBy(d =&gt; d.BValue)) { item.BRanking = count; count++; } count = 1; foreach (Data item in RankingData.OrderBy(d =&gt; d.CValue)) { item.CRanking = count; count++; } } } </code></pre> <p>The problem I am trying to solve is I want to write something roughly like this:</p> <pre><code>public void RankData&lt;V, R&gt;() { int count = 1; foreach(Data item in RankingData.OrderBy(V)) { item.R = count; count++; } } </code></pre> <p>So that as I need to alter the ranking logic (for example, handle tie breaking rules) that I write the code once instead of copying the code 20 times to make the rules match. What am I missing?</p> <p><strong>UPDATE</strong></p> <p>Using Tanzelax's solution as a base this is the extension class I came up with:</p> <pre><code>public static class RankingExtension { public static void SetRanking&lt;TKey&gt;(this List&lt;Data&gt; dataSet, bool Ascending, Func&lt;Data, TKey&gt; getOrderBy, Action&lt;Data, int&gt; setRank) where TKey : IComparable { var ordered = (Ascending) ? dataSet.OrderBy(getOrderBy) : dataSet.OrderByDescending(getOrderBy); int i = 1; foreach (Data item in ordered) { setRank(item, i); i++; } } } </code></pre> <p>I had to add in a switch so that I could control whether or not the field was being sorted ascending or not. And in my test scenarios it produces the appropriate output:</p> <pre><code> List&lt;Data&gt; test = new List&lt;Data&gt;(); test.Add(new Data { AValue = 25, BValue = 1.25, CValue = 99.99 }); test.Add(new Data { AValue = 89, BValue = 2.10, CValue = 1.01 }); test.Add(new Data { AValue = 10, BValue = 6, CValue = 45.45 }); test.Add(new Data { AValue = 15, BValue = 2.33, CValue = 2.99 }); test.Add(new Data { AValue = 90, BValue = 5.43, CValue = 27.89 }); test.SetRanking(false, d =&gt; d.AValue, (d, i) =&gt; d.ARank = i); test.SetRanking(false, d =&gt; d.BValue, (d, i) =&gt; d.BRank = i); test.SetRanking(true, d =&gt; d.CValue, (d, i) =&gt; d.CRank = i); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload