【问题标题】:Sorting a list of objects of multiple data types对多个数据类型的对象列表进行排序
【发布时间】:2015-06-24 13:33:49
【问题描述】:

我的代码中有这个类

class Stock
{
    public DateTime Date;
    public string Day;
    public double Open, Close, Diff;
    public int Volume;

    public Stock(double open, double close, double diff, int volume, string day, DateTime date)
    {
        this.Open = open;
        this.Close = close;
        this.Diff = diff;
        this.Volume = volume;
        this.Day = day;
        this.Date = date;
    }
}

在另一个类中,我想创建一个冒泡排序,它将对传递给它的股票列表 (List<Stocks>) 进行排序,我对此有多个问题,主要问题是数据类型,比较两个值并不容易当它们可能是stringintdoubleDateTime 时。我已经使用TryParse 来检查有效数据类型的方法完成了它,但我正在寻找一个干净的解决方案,这是我迄今为止的尝试

public void BubblesortBy(int sortBy, List<Stock> Stocks)
{

    Type objType = typeof(Stock);
    FieldInfo[] fields = objType.GetFields();

    Stock temp = null;
    int loopCount = 0;
    bool doBreak = true;

    for (int i = 0; i < Stocks.Count; i++)
    {
        doBreak = true;
        for (int j = 0; j < Stocks.Count - 1; j++)
        {
            if (Compare(fields[sortBy - 1].FieldType.ToString(), fields[sortBy].GetValue(Stocks[j]), fields[sortBy].GetValue(Stocks[j+1])))
            {
                temp = Stocks[sortBy + 1];
                Stocks[sortBy + 1] = Stocks[sortBy];
                Stocks[sortBy] = temp;
                doBreak = false;
            }
            loopCount++;
        }
        if (doBreak) { break; /*early escape*/ }
    }
}

传递给它的int 决定是否排序,这就是我使用反射的原因,以便可以通过数字访问变量。

  1. 日期
  2. 打开
  3. 关闭
  4. 区别
  5. 音量

【问题讨论】:

  • 我建议使用 switch 语句并根据案例块中的数据类型进行比较。
  • 您是将冒泡排序作为一种学习练习,还是出于实际目的?出于 99.9% 的实际目的,不要实现自己的排序算法。
  • @TimS。对于学习,我将如何有效地检查数据类型?

标签: c# list class sorting reflection


【解决方案1】:

您为什么要自己实施排序?查看IComparable

编辑:

一种很好且类型安全的方式将要排序的字段传递到方法中而无需重新引用,它将是:

BubblesortBy(x => x.FieldName, stockes);

public void BubblesortBy<T>(Func<Product, T> sortBy, List<Stock> Stocks)
{
    Stock temp = null;
    int loopCount = 0;
    bool doBreak = true;

    for (int i = 0; i < Stocks.Count; i++)
    {
        doBreak = true;
        for (int j = 0; j < Stocks.Count - 1; j++)
        {
            if (Compare(sortBy(Stocks[j]), sortBy(Stocks[j + 1])))
            {
                temp = Stocks[sortBy + 1];
                Stocks[sortBy + 1] = Stocks[sortBy];
                Stocks[sortBy] = temp;
                doBreak = false;
            }
            loopCount++;
        }
        if (doBreak)
            break; /*early escape*/
    }
}

【讨论】:

  • @RaymondTunstill 在我的帖子中添加了示例
【解决方案2】:

您不应假设GetFields 返回的字段将按特定顺序排列。

GetFields 方法不返回特定顺序的字段,例如字母顺序或声明顺序。您的代码不得依赖于返回字段的顺序,因为该顺序会有所不同。

一种选择是使用lambdas,就像LINQ 的OrderBy 方法一样。使用泛型类型还可以使您的代码更具可重用性,并使您的 Compare 方法等内容更简单。

public void BubblesortBy<TSource, TKey>(Func<TSource, TKey> keySelector,
                                        List<TSource> stocks)
{
    int loopCount = 0;
    bool doBreak = true;

    for (int i = 0; i < stocks.Count; i++)
    {
        doBreak = true;
        for (int j = 0; j < stocks.Count - 1; j++)
        {
            if (Compare(keySelector(stocks[j]), keySelector(stocks[j+1])))
            {
                TSource temp = stocks[j + 1];
                stocks[j + 1] = stocks[j];
                stocks[j] = temp;
                doBreak = false;
            }
            loopCount++;
        }
        if (doBreak) { break; /*early escape*/ }
    }
}
private bool Compare<T>(T l, T r)
{
    return Comparer<T>.Default.Compare(l, r) > 0;
}

// use like
BubblesortBy(x => x.Close, myList);

【讨论】:

  • 感谢@Tim S. 的回答,当我收到错误“方法'Stocks.Program.Sort.BubblesortBy(System. Func, System.Collections.Generic.List)' 无法从用法中推断出来。尝试使用 Sort.BubblesortBy(secondNumber, Stocks); 显式指定类型参数
  • @Raymond 我现在添加了一个示例。使用像 x =&gt; x.Volume 这样的 lambda 而不是 int 来指示要使用哪个字段进行比较。
  • 这个答案正是我想要的,以了解 Func keySelector 如何工作?我以前从未使用过 IComparable 函数
  • @RaymondTunstill Func&lt;TSource, TKey&gt; 是代表。 x =&gt; x.Close 是一个 lambda。您不会以任何方式直接使用IComparable,但Comparer&lt;T&gt;.Default 确实使用了它。阅读这些内容,以更好地了解这里发生的事情。如果你把这段代码分解成它的组件,它是很容易理解的。
猜你喜欢
  • 2015-01-03
  • 1970-01-01
  • 2020-02-23
  • 2023-04-01
  • 1970-01-01
  • 2015-05-31
  • 1970-01-01
  • 2020-11-06
  • 2019-06-09
相关资源
最近更新 更多