J'ai un objet dans une liste dont j'ai besoin de classer de différentes manières. Actuellement, le code est plutôt lourd car il nécessite que j'adresse individuellement chaque colonne. Exemple:Traitement des données de classement w/C# & LINQ
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<Data> RankingData { get; set; }
public void RankData()
{
int count = 1;
foreach (Data item in RankingData.OrderBy(d => d.AValue))
{
item.ARanking = count;
count++;
}
count = 1;
foreach (Data item in RankingData.OrderBy(d => d.BValue))
{
item.BRanking = count;
count++;
}
count = 1;
foreach (Data item in RankingData.OrderBy(d => d.CValue))
{
item.CRanking = count;
count++;
}
}
}
Le problème que je tente de résoudre est que je veux écrire quelque chose à peu près comme ceci:
public void RankData<V, R>()
{
int count = 1;
foreach(Data item in RankingData.OrderBy(V))
{
item.R = count;
count++;
}
}
Alors que je dois modifier la logique de classement (par exemple, la poignée départage règles) que j'écris le code une fois au lieu de copier le code 20 fois pour faire correspondre les règles. Qu'est-ce que je rate?
MISE À JOUR
En utilisant la solution de Tanzelax comme base c'est la classe d'extension, je suis venu avec:
public static class RankingExtension
{
public static void SetRanking<TKey>(this List<Data> dataSet, bool Ascending, Func<Data, TKey> getOrderBy, Action<Data, int> 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++;
}
}
}
je devais ajouter un interrupteur pour que je puisse contrôler si oui ou non la le champ était trié ascendant ou non. Et dans mes scénarios de test, il produit la sortie appropriée:
List<Data> test = new List<Data>();
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 => d.AValue, (d, i) => d.ARank = i);
test.SetRanking(false, d => d.BValue, (d, i) => d.BRank = i);
test.SetRanking(true, d => d.CValue, (d, i) => d.CRank = i);
Votre code n'était pas tout à fait là, mais il m'a fait sacrément fermer. Je posterai ma modification dans un peu. – thaBadDawg
@thaBadDawg: Content que je puisse aider. :) Pourrait également générique sur les données et autres joyeusetés. De plus, au lieu de passer un booléen ascendant, vous pourriez simplement passer CValue négatif dans orderBy lambda, bien que je suis sûr que beaucoup de gens s'opposeraient à cette approche. – Tanzelax