【问题标题】:How to sort a collection of objects, which has to be sorted based on some constantly changing parameters如何对一组对象进行排序,必须根据一些不断变化的参数进行排序
【发布时间】:2012-04-14 01:23:05
【问题描述】:

我正在研究如何使用加权值有效地对列表进行排序。

每个项目都有一个 ID、名称和文件路径。每个项目还有一个值列表,这些值分配了一个百分比,显示它们与每个值的相关程度。

我需要对列表进行排序,以便列表顶端的项目是与当前参数最相关的项目。

让我们说,

项目一:

  • A:50,B:30,C:20,D:10
  • X:50,Z:20

项目二:

  • A:100, B:0, C:0, D:0
  • X:0, Z:100

我的参数是 A 和 Z。显然,项目二应该在我的列表顶部,因为它是最相关的项目。但是我将如何实施呢?

奖励:如果能够进行轻微的随机化也很好,我不希望每次都获得最终的相关项目。

谢谢

【问题讨论】:

  • 请提供更多信息。你试过什么?为了排序,您将如何计算每个项目的价值?你会添加参数吗?将它们相乘?您是否将这些项目存储在List<T> 中? List<T> 有一个方法 Sort 接受委托。你试过用那个吗?
  • 您想要随机排序?这有什么意义?
  • 嗯,我希望它排序,所以我得到更多相关的项目。但我不希望每次都是最相关的,所以需要有一点随机性。我以前使用过 List.Sort 方法,但我不确定这是否是解决此类问题的最佳做法。
  • 听起来您正在寻找优先队列。 C# 没有内置的,但是如果您搜索该术语,您会发现很多人提供他们自己的实现,因为这是一个常见的实际和学术问题。

标签: c# list sorting weighted


【解决方案1】:

假设你知道你的权重函数,你可以使用 Linq to Objects:

var sorted = (from o in myList orderby o.SortingValue select o).ToList();

在此示例中,SortingValue 将是对象上的一个属性,它封装了您问题中的属性并将实现您的算法。

SortingValue 的示例算法:

您可以使用字典来保存相关百分比

然后,您的“当前参数”可以用作字典的键以获得相关权重:

Dictionary<string, double> weightDictionary = // Load somehow

double SortingValue
{
    get {
        double sortingValue;

        foreach(string currentParameter in currentParameters)
        {
            sortingValue += weightDictionary[currentParameter];
        }

        // You could use Math.Random to get a number between say -0.1 and -.1.  
        // Multiply sortingValue by that random number.
        return sortingValue;
    }
}

【讨论】:

  • 只是一个更新,这与我的排序方式非常相似,为这个想法喝彩!
【解决方案2】:

很久以前,我为此目的创建了一个扩展方法。我刚刚又遇到了对它的需求:

public static IOrderedEnumerable<TSource> OrderByWeight<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, int> weighting) where TKey : IComparable
{
    Dictionary<TSource, int> order = new Dictionary<TSource, int>();
    foreach (TSource item in source)
    {
        if (!order.ContainsKey(item)) order.Add(item, weighting(keySelector(item)));
    }
    return source.OrderBy(s => order[s]);
}

你可以这样使用它:

var data = dt.Select(g => new
{
    Season = g.season,
    AverageTemp = g.temp
}).OrderByWeight(a => a.Season, x =>
{
    if (x == "WINTER") return 1;
    if (x == "SPRING") return 2;
    if (x == "SUMMER") return 3;
    if (x == "AUTUMN") return 4;
    return 99;
});

来源:from my old blog

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-21
    • 2012-04-03
    • 2022-01-28
    相关资源
    最近更新 更多