【问题标题】:Evaluate elements according to their order根据元素的顺序评估元素
【发布时间】:2021-07-07 11:44:30
【问题描述】:

我想根据它们的顺序(按它们的值排序)评估在我的 List 中保存数字值的元素并将它们放入 List,其中 Key 是原始元素,Value 是评估顺序。我的问题是我不知道如何处理元素中的无关值 - 它们应该是平均顺序。

例如:

double[]{2,4,4,4,7,8,40} 我想要double[]{1,3,3,3,5,6,7}

我已经对该列表进行了排序:

for (int i = 0; i < CriterionsNumber; i++)
{
    variants[i].Criterions.OrderByDescending(value => value.Value).ToList();
}

Thank you.

【问题讨论】:

  • 真的不清楚您要做什么,或者您在此处发布的代码有什么问题。不过有一点很突出,OrderByDescending 返回一个排序列表,它根本不会影响源数据。
  • 如果只有2个值为4的元素怎么办?那么平均订单将是 2.5。
  • @HansKilian 是的,如果有 2 个元素的值为 4,它看起来像:int[]{1,2.5,2.5,4,5,6}。我已经有一个带顺序的有序列表(作为索引),但我必须按照它们的顺序评估这些元素,因为可以有两个相同的值。
  • 将 2.5 放入整数数组中有点困难
  • @HansKilian 哦,是的,我的错。这只是一个简单的例子来展示我想要的东西。在我的 Variant-Criteiron 结构中,当然有 double 值。

标签: c# list sorting


【解决方案1】:

您想为每个项目计算Rank:有{2,4,4,4,7,8,40} 得到

  • {1,2,2,2,5,6,7}(分钟作为决胜局)
  • {1,3,3,3,5,6,7}(平均作为决胜局)
  • {1,4,4,4,5,6,7}(max 作为决胜局)

Linq 解决方案;既然你想通过计算平均来打破平局,我们就用Average:

  int[] source = new int[] { 2, 4, 4, 4, 7, 8, 40};

  List<int> result = source
    .OrderBy(item => item)
    .Select((item, index) => new { item, index = index + 1})
    .GroupBy(item => item.item, item => item.index)
    .SelectMany(group => group.Select(x => (int)(group.Average())))
    .ToList(); 

让我们看看:

  Console.WriteLine(string.Join(", ", result));

结果:

  1, 3, 3, 3, 5, 6, 7

将Min 或Max 替换为Average 以获得不同的平局

【讨论】:

    【解决方案2】:

    此函数对索引进行排序,但是当值重复时,它会获取平均值。我想这就是你的意思。请注意,平均指数可能是 2.5 之类的分数(否则您将不得不添加四舍五入):

    
    public void SortAverageIndex(double[] ArrayIn, out double[] ArrayOut)
            {
    
                 Array.Sort(ArrayIn);
    
                ArrayOut = new double[ArrayIn.Length]; 
    
                int prevIndex = 0;
                double prevVal = ArrayIn[0];
                for (int i = 1; i < ArrayIn.Length; i++)
                {
                    if (ArrayIn[i] != prevVal)
                    {
                        double AverageIndex = (i + prevIndex - 1) / 2.0 +1;
                        prevVal = ArrayIn[i];
                        int index = prevIndex;
                        for (int j = prevIndex; j < i; j++)
                            ArrayOut[j] = AverageIndex;
    
                        prevIndex = i;
                    }
                }
    
                double AverageIndexFinal = (ArrayIn.Length + prevIndex-1) / 2.0 + 1;            
                for (int j = prevIndex; j < ArrayIn.Length; j++)
                    ArrayOut[j] = AverageIndexFinal;
    
            }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-26
      • 1970-01-01
      相关资源
      最近更新 更多