对List<>中的对象进行排名按多个标准

时间:2011-04-18 15:11:10

标签: c# list ranking

我有一个代表植物的对象列表 - 每个对象都有成员属性,代表一系列可容忍的环境条件。

我想重新排序此列表,以便工厂对象按适用性排列。

我想我想根据温度/ pH范围的中间值与所提供的环境数据的接近程度,为列表中的每个项目提供温度/ pH适用性等级。

然后我会对排名进行平均并按此数字对列表进行排序。

但是,我不确定跟踪列表中每个项目的排名的最佳方法是什么。有没有人对如何最好地解决这个问题有任何建议?

8 个答案:

答案 0 :(得分:2)

你可以这样做:

var plants = new Plant[] { new Plant { T = 1, Ph = 2 },  new Plant { T = 2, Ph = 2 } };

var ps = from p in plants
         let magicNumber = p.T/p.Ph // Or some other algorithm
         orderby magicNumber
         select p;

然后你可以从Plant的属性中创建你喜欢的任何数字,而不必实现Comparer。

答案 1 :(得分:0)

您可以使用LINQ OrderBy扩展方法。现在,通常你可以这样写:

 mySet.OrderBy(x => x.SomeProperty)

但是,如果要按多个属性排序,只需创建一个定义值的方法:

mySet.OrderBy(x => CreateValueFor(x))

然后CreateValueFor返回特定值。例如,创建一个定义它的适用性的整数,它实际上是对象上某些属性的函数。

答案 2 :(得分:0)

公开在课堂上计算适合度的方法,然后使用LINQ OrderBy扩展名

public int GetSuitabilityIndex()
{
     //Calculate suitability..
}


var sorted = myList.OrderBy(item=>item.GetSuitabilityIndex());

答案 3 :(得分:0)

在你的情况下,听起来你最好使用自定义比较器,你可以通过你的环境设置:

class PlantComparer : IComparer<Plant>
{
    public PlantComparer(PlantEnvironmentSettings settings)
    {

    }

    public int Compare(Plant plant1, Plant plant2)
    {
        //compare two plants, return 0, 1 or -1 
        return 0;
    }
}

然后你可以在排序中使用它:

List<Plant> plants = new List<Plant>();
..
PlantEnvironmentSettings settings = new PlantEnvironmentSettings();
plants.Sort(new PlantComparer(settings));

答案 4 :(得分:0)

您需要一种方法来计算某个项目的排名,我们称之为GetRank,然后您可以在Sort方法中使用Comparison

plants.Sort((x,y) => GetRank(x).CompareTo(GetRank(y)));

您还可以使用OrderBy扩展方法,该方法接受一个返回每个项目值的委托:

plants = plants.OrderBy(x => GetRank(x)).ToList();

计算排名的方法不一定是命名方法,您可以通过简单地用Comparison替换任何表达式将代码直接放在OrderByGetRank(n)委托中你喜欢。

答案 5 :(得分:0)

假设您想要显示各种适用性标准而不仅仅是有序的工厂列表,我认为您需要定义一个包含额外数据的类:

class PlantRankings
{
    public Plant Plant { get; set; }
    public double PhSuitabilityScore { get; set; }
    public double SoilTypeScore { get; set; }
    public double SmellsNiceScore { get; set; }

    public double RankingScore { get; set; } // could compute on-the-fly here
}

并将您的植物映射到该类,然后按照那里的组合分数进行排序。我想你会写一个接受Plant的方法,然后你的标准返回了一个排名结构,例如

var rankedPlants = plants.Select(p => ScoreSuitability(p, criteria))
                         .OrderBy(pr => pr.RankingScore).ToList();

如果按等级排序,则表示每个标准按每个标准进行1-N排名,那么我认为您需要生成扩展结构,但

public int PhSuitabilityRank { get; set; }

除了分数;然后,一旦你计算了分数并建立了列表,你就可以

int rank = 1;
for(var rankedPlant in
           rankedPlants.OrderByDescending(pr => pr.PhSuitabilityScore))
{
    rankedPlant.PhSuitabilityRank = rank;
    ++rank;
}

等等。 (可能有一种方法可以在LINQ中执行此操作,但在Order结果中没有.ForEach(),我认为这更清晰,更简单。)

答案 6 :(得分:0)

您可以使用linq或lambda表达式对行星列表进行排序 按排名顺序,它将为您提供排序列表。

答案 7 :(得分:-1)

难道你不能简单地调用Sort方法,传入一个比较方法,该方法的评估方式完全按照你刚才描述的方式进行评估吗?