根据计算出的属性索引对列表进行排序

时间:2018-07-04 15:57:40

标签: c# .net sorting indexing

我有以下课程。

 public class Header
    {
        public long CombinedIndex { get; private set; }
        public int Key { get; set; } //Unique
        public bool IsRequired { get; set; }// True or false
        public DateTime? AvailableDate { get; set; } // null or date value
        public int Index { get; set; } // a number and can be same among other Header 

        public void CalculateCombinedIndex()
        {
            CombinedIndex = Key + (IsRequired ? 0 : 1) + Index + (AvailableDate ?? DateTime.MaxValue).Ticks;
        }
    }

预计大约有50,000个实例 排列成一个数组。我需要按以下顺序对其进行排序:

  • 首先基于IsRequired
  • 然后索引
  • 可用日期(日期值接近当前日期)
  • 键(主键)

说所有这些属性值之和和 得出一个唯一的数字,然后仅对该数字进行排序。 以后,标题列表可以转换为字典,其中 关键是CombinedIndex,我已经排序的数组可以查找 字典,以便我迭代数组。效率如何 保证这一切看起来都很好吗?

3 个答案:

答案 0 :(得分:2)

我会用LINQ做到这一点:

public class Header : IComparable
{
    public long CombinedIndex { get; private set; }
    public int Key { get; set; } //Unique
    public bool IsRequired { get; set; }// True or false
    public DateTime? AvailableDate { get; set; } // null or date value
    public int Index { get; set; } // a number and can be same among other Header 

    public void CalculateCombinedIndex()
    {
        CombinedIndex = Key + (IsRequired ? 0 : 1) + Index + (AvailableDate ?? DateTime.MaxValue).Ticks;
    }

    public int CompareTo(object obj)
    {
        if (obj == null) return 1;

        Header otherHeader = obj as Header;
        if (otherHeader != null)
        {
            if (this.IsRequired && !otherHeader.IsRequired)
                return 1;
            if (!this.IsRequired && otherHeader.IsRequired)
                return -1;
            if (this.Index > otherHeader.Index)
                return 1;
            if (this.Index < otherHeader.Index)
                return -1;
            //// ....
            return 0;
        }
        else
            throw new ArgumentException("Object is not a Temperature");
    }
}

仅在平局的情况下才使用下一个条件。因此,无需创建一个组合索引,该索引将使更改顺序逻辑变得非常困难,并且无论如何似乎都已被破坏。

答案 1 :(得分:1)

如果您需要根据给定类型的投影键执行比较操作,我发现拥有一个KeyComparer类可以从IComparer<TSource>创建一个Func<TSource, TKey>实例的情况下会有所帮助代表。这与C#7中引入的新元组语法特别有效。这是生成的语法的示例:

// Create an IComparer<Header> instance based on your combined key.
var comparer = KeyComparer.Create((Header h) => (h.IsRequired, h.Index, h.AvailableDate, h.Key));

List<Header> headers = ...

// Sort the list using the combined key.
headers.Sort(comparer);

// Convert to a dictionary keyed by the combined key.
var dict = headers.ToDictionary(comparer.KeySelector);

这是该类的示例实现。 (有关详细说明,请参见my blog post。)

public static class KeyComparer
{
    public static KeyComparer<TSource, TKey> Create<TSource, TKey>(
        Func<TSource, TKey> keySelector,
        IComparer<TKey> innerComparer = null)
    {
        return new KeyComparer<TSource, TKey>(keySelector, innerComparer);
    }
}

public class KeyComparer<TSource, TKey> : Comparer<TSource>
{
    protected internal KeyComparer(
        Func<TSource, TKey> keySelector,
        IComparer<TKey> innerComparer = null)
    {
        KeySelector = keySelector ?? throw new ArgumentNullException(nameof(keySelector));
        InnerComparer = innerComparer ?? Comparer<TKey>.Default;
    }

    public Func<TSource, TKey> KeySelector { get; }
    public IComparer<TKey> InnerComparer { get; }

    public override int Compare(TSource x, TSource y)
    {
        if (object.ReferenceEquals(x, y))
            return 0;
        if (x == null)
            return -1;
        if (y == null)
            return 1;

        TKey xKey = KeySelector(x);
        TKey yKey = KeySelector(y);
        return InnerComparer.Compare(xKey, yKey);
    }
}

答案 2 :(得分:0)

只需实现IComparable,您就可以使用List.Sort()。

Proxy