Nate
Nate

Reputation: 2492

Map two values to one object

I am trying to write a function in C# that will take two small int values (range 0-3) and return a Color object based on those values. The problem is that there is no way to programmatically determine the color from the two values, they are specific to a type of LED and must be hardcoded.

The simplest way I can think of would be a massive (16 cases) if-else statement that will check each value, but this doesn't seem like a very elegant solution. Is there a better way to determine the Color?

Upvotes: 3

Views: 1817

Answers (7)

Jimmy Hoffa
Jimmy Hoffa

Reputation: 5967

I vote an enum for the 16 colors

enum Color
{
    red = 0,
    blue = 1
}

public Color GetColor(int v1, int v2)
{
    int colorValue = v1 << 8;
    colorValue |= v2;
    return (Color)colorValue;
}

Upvotes: 0

Dr. Wily&#39;s Apprentice
Dr. Wily&#39;s Apprentice

Reputation: 10280

The fact that you have these two small integer values that combine together to mean something (at least a color) suggests to me that it might make sense for you to have a struct defined to encapsulate them.

The benefit of doing that is that you can use the struct as the key to a dictionary: the Equals and GetHashCode methods should already work adequately.

Below is an example. Since you mentioned that the colors cannot be calculated, I've left a comment where the dictionary needs to be populated; you could hard-code this, but ideally you'd read the values from a file or embedded resource.

EDIT: updated my example struct to be immutable.

struct MyStruct
{
    private byte _X;
    private byte _Y;

    public MyStruct(byte x, byte y)
    {
        _X = x;
        _Y = y;
    }

    public byte X { get { return _X; } }
    public byte Y { get { return _Y; } }

    private static Dictionary<MyStruct, Color> _ColorMap;

    static MyStruct()
    {
        _ColorMap = new Dictionary<MyStruct, Color>();

        // read color mapping from somewhere...perhaps a file specific to the type of LED
    }

    public Color GetColor()
    {
        return _ColorMap[this];
    }
}

Upvotes: 0

Matthew Flaschen
Matthew Flaschen

Reputation: 284927

If you want to go the OO approach (for better or worse), you can use a Tuple->Color mapping:

Dictionary<Tuple<int, int>, Color> d = new Dictionary<Tuple<int, int>, Color>()
{
  {Tuple.Create(2, 1), Color.Red},
  {Tuple.Create(1, 1), Color.Blue},
  {Tuple.Create(1, 2), Color.Green}
};

One advantage over a 2-d array is it can be sparse without nulls. You can also use a collection initializer without initializing in index order. This will throw an obvious ArgumentException at initialization time if you try to use the same tuple for two colors.

Upvotes: 2

Oleg Kolosov
Oleg Kolosov

Reputation: 1588

How about:

static Color GetColor(int c1, int c2)
{
  if (c1 > 3 || c1 < 0 || c2 > 3 || c2 < 0)
    throw new ArgumentOutOfRangeException();

  var map = new Dictionary<string, Color>
  {
    {"00", Color.Black},
    {"10", Color.Red},
    {"20", Color.Blue},
    // etc, etc...
    {"11", Color.DimGray},
  };

  var key = c1.ToString() + c2.ToString();
  return map[key];
}

Upvotes: 0

Kirk Woll
Kirk Woll

Reputation: 77576

What about a two dimensional array of Color objects?

Color[,] colors = new[,] {
    { Color.FromArgb(1, 2, 3), Color.FromArgb(3, 4, 5), Color.FromArgb(6, 7, 8), Color.FromArgb(9, 10, 11) },
    { Color.FromArgb(21, 22, 23), Color.FromArgb(23, 24, 25), Color.FromArgb(26, 27, 28), Color.FromArgb(29, 30, 31) },
};

Color color = colors[index1, index2];

Upvotes: 2

AllenG
AllenG

Reputation: 8190

The prefered method of avoid a bunch of if else statements is to use Switch. You could also use an enum and assign int values which correspond to your small ints:

public enum ColorChoice
{
  red = 01 //'01' instead of '1' to make clear your first digit is zero
  blue = 02
  green = 03
  ...etc...
]

Upvotes: -3

Justin Ethier
Justin Ethier

Reputation: 134207

As a slightly cleaner alternative to using if / else, you could place the color values in an array, and use the two small int values as indexes into the array.

Upvotes: 1

Related Questions