索引数组由多个元素组成

时间:2014-01-28 09:03:46

标签: c# collections indexing

在C#中,我正在使用SortedSet来获取由三个字段组成的结构的索引:

public struct ChannelId : IComparable<ChannelId>
{
    public int ChanNumber;
    public Tower ChanTower;
    public double AvailableProbability;

    public int CompareTo(ChannelId other)
    { return other.AvailableProbability.CompareTo(AvailableProbability); }
}

(是的,CompareTo函数是正确的。我想按相反的顺序。)所以,我想要一些可以在这里用两个字段索引的集合/结构,(ChanNumber以及)。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:1)

您可以使用自定义比较器创建两个集:

class ChanNumberComparer : IComparer<ChannelId>
{
    public int Compare(ChannelId x, ChannelId y)
    {
        return y.ChanNumber.CompareTo(x.ChanNumber);
    }
}

SortedSet构造函数

中使用它

答案 1 :(得分:0)

我假设你需要能够根据ChanNumber和ChanTower查找ChannelId。

但是,我认为班级名称用词不当。

我会创建两个类:

类ChannelID:

  • int ChanNumber
  • Tower ChanTower

课程频道:

  • ChannelID ChanID
  • double AvailableProbability

然后,字典可以很好地满足您的需求:

Dictionary<ChannelID, Channel>

您需要为ChannelID实现GetHashCode和Equals方法。然后,您只需创建一个新的ChannelID对象作为查找,以获取字典中的Channel对象,您可以在其中获取AvailableProbability值。

以下完整代码:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Test
{
    class ChannelTest
    {
        public static void Test()
        {
            var dict = new Dictionary<ChannelID, Channel>();

            var a = new Channel(new ChannelID(0, Tower.A), 0.5);
            var b = new Channel(new ChannelID(7, Tower.B), 0.35);

            dict.Add(a.ChanID, a);
            dict.Add(b.ChanID, b);

            // To get a channel from the ID
            // Just create a new ID object with the same values
            var aRef = dict[new ChannelID(0, Tower.A)];
            var bRef = dict[new ChannelID(7, Tower.B)];

            // If you want the sorted channels - use linq
            // This will give you the best 10
            var sorted = dict.Values.OrderByDescending(c => c.AvailableProbability).Take(10).ToList();

        }
    }

    class ChannelID
    {
        public int ChanNumber { get; private set; }
        public Tower ChanTower { get; private set; }

        public ChannelID(int chanNumber, Tower chanTower)
        {
            ChanNumber = chanNumber;
            ChanTower = chanTower;
        }

        public override bool Equals(object obj)
        {
            if (!(obj is ChannelID))
            {
                return false;
            }

            var o = (ChannelID)obj;

            return this.ChanNumber == o.ChanNumber
                && this.ChanTower == o.ChanTower;
        }

        public override int GetHashCode()
        {
            // Using random prime multipliers to get a good hash code distribution
            // http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode
            return 17
                + 23 * this.ChanNumber.GetHashCode()
                + 23 * this.ChanTower.GetHashCode();
        }
    }

    class Channel : IComparable<Channel>
    {
        public ChannelID ChanID { get; private set; }
        public double AvailableProbability { get; private set; }

        public Channel(ChannelID chanID, double availableProbability)
        {
            ChanID = chanID;
            AvailableProbability = availableProbability;
        }

        public int CompareTo(Channel other)
        { return other.AvailableProbability.CompareTo(AvailableProbability); }
    }

    enum Tower
    {
        A,
        B,
        C
    }
}