I need to display the List of a Dictionary based on the int key I've entered in the console and throw an error message if it out of the given bounds of inputs in the console as well.

public class Channel
{
    const string displayChannel = "{0},{1},{2}";

    private Dictionary <int, string> ChannelLookup = 
    new Dictionary <int, string> ()
    {
        {1, new List<string>{"[A]","[B]","[C]"}},
        {2, new List<string>{"[A]"}
    };

    public string channelDisplay (int val)
    {
        if (!ChannelLookup.ContainsKey(val))
        {
            // throw exception
        }
        else
        {
            string display = string.Format(displayChannel, ChannelLookup[val]);
            return display;
        }
    }
}

System.Format.Exception:'Index(zerobased) must be greater than or equal to zero and less than the size of the argument list.

3 Answers

0
Community On

.NET doesn't let you have unused format parameters, i.e. you can't do this string.Format("{0},{1}", "first value") without also providing a value for {1}.

Your best bet here is probably string.Join. string.Join will concatenate the values you provide to it, placing the specified delimiter between each value.

See the docs here

public class Channel
{
 private Dictionary <int, string> ChannelLookup = 
 new Dictionary <int, string> ()
 {
  {1, new List<string>{"[A]","[B]","[C]"}},
  {2, new List<string>{"[A]"}
 };

 public string channelDisplay (int val)
 {
  if(!ChannelLookup.ContainsKey(val))
  {
    // throw exception
  }
  else
  {
    string display = string.Join(",", ChannelLookup[val]);
    return display;
  }
 }
}
1
Dmitry Bychenko On

You have to display arbitrary number of items (say, 3 - "[A]", "[B]", "[C]" or just 1 - "A"); let's Join them instead of using Format

public class Channel {
  private Dictionary <int, List<string>> ChannelLookup = 
    new Dictionary <int, List<string>> () {
      {1, new List<string>() {"[A]", "[B]", "[C]"} },
      {2, new List<string>() {"[A]"} },
    };

  public string channelDisplay (int key) {
    if (ChannelLookup.TryGetValue(key, out var items))
      return string.Join(",", items);
    else 
      throw new ArgumentException($"{nameof(key)} = {key} not found", nameof(key));
  }
}

Or even

public string channelDisplay(int key) => ChannelLookup.TryGetValue(key, out var items)
  ? string.Join(",", items)
  : throw new ArgumentException($"{nameof(key)} = {key} not found", nameof(key));
2
Emaro On

Just for completeness: Sometimes I use Aggregate instead of Join, since it gives you more control.

var values = ChannelLookup[val].Values;
var display = values.Aggregate((a, b) => $"{a}, {b}");

To use the Linq function Aggregate, you need to add System.Linq to your using directives.