0

Edit: I don't feel this was duplicate- I did fail to elaborate clearly that I wanted to know an efficient way to pad char's to the left of my dictionary values. The question I marked as answer should clarify as it is a very different answer than the answer in other thread. Sorry, I worded it wrong.

I am trying to verify that all the values within my Dictionary are a certain length, and if they are not, pad them with '0' to the left. I know "what" the issue is, I am reading through the dictionary's KVP and then modifying it which of course throws an exception, but I am not sure how to modify my code to make it "legal"

class prefixMe
{
    Dictionary<string, string> d = new Dictionary<string, string>();

    public prefixMe()
    {
        d.Add("one", "123456");
        d.Add("two", "678");
        d.Add("three", "13");

        foreach(KeyValuePair<string,string> k in d)
        {
            StringBuilder sb = new StringBuilder(k.Value);
            while(sb.Length != 10)
            {
                Console.WriteLine("Key:{0}\tValue:{1}", k.Key, sb);
                sb.Insert(0, '0');
            }
            d[k.Key] = sb.ToString();
            //k.Value.Replace(k.Value, sb.ToString());// = sb.ToString();
            Console.WriteLine("Key:{0}\tNew Value:{1}", k.Key, d[k.Key]);
            break;
        }

    }
}

The break; stops the code from throwing an error, but also makes it so it does not go through for the other values as it breaks out of the foreach loop.

The result should be:

0000123456
0000000678
0000000013
Nyra
  • 859
  • 1
  • 7
  • 27
  • You can avoid the issue with a helper function for adding to the list: `void add(string key, string val) {d.Add(key, val.PadLeft(10, '0'));}` – 001 May 23 '14 at 13:39

5 Answers5

7

Use

foreach(KeyValuePair<string,string> k in d.ToList())

instead of

foreach(KeyValuePair<string,string> k in d)

This creates a list of the key-value-pairs, through which you then iterate. This means that in the loop you can touch the dictionary.

If you don't mind creating a new dictionary, then you can also replace the dictionary quite easily using Linq.

d = d.ToDictionary(x => x.Key, x => x.Value.PadLeft(10, '0'));
Maarten
  • 22,527
  • 3
  • 47
  • 68
  • upvoted. One liner Linq answer could replace 80% code in the question. – Hassan May 23 '14 at 13:53
  • 1
    This works perfect- no I am absolutely fine with making new dictionary- I am just new to LINQ. I figured there was a more efficient way to do this. Thank you! – Nyra May 23 '14 at 13:54
  • Also for what it is worth, I added this where clause to ignore null/empty values from being padded with all zero's (in my program I want them to remain null/empty) d = d.Where(x => !string.IsNullOrEmpty(x.Value)).ToDictionary(x => x.Key, x => x.Value.PadLeft(10, '0')); – Nyra May 23 '14 at 14:08
2

Use a for loop instead of a foreach loop. This will allow you to iterate through the Dictionary and modify it in the same go.

EDIT: Upon further Googling/trying to compile a for loop through a dictionary, it seems you can't actually do this. I found How to modify key in a dictionary in C#, it seems you can't even change a key without removing it. So maybe this question will be helpful to you.

Community
  • 1
  • 1
eddie_cat
  • 2,527
  • 4
  • 25
  • 43
1

Use PadLeft method, and do not break your loop on first iteration.

public prefixMe()
{
    d.Add("one", "123456");
    d.Add("two", "678");
    d.Add("three", "13");

    foreach(var k in d.ToList())
    {
        if(k.Value.Length != 10) 
          d[k.Key]  = k.Value.PadLeft(10, '0');
    }

}

ToList will allow you to modify your dictionary.

Selman Genç
  • 100,147
  • 13
  • 119
  • 184
  • if this works, it would also be very helpful, I went with just transferring the entire dictionary and padding accordingly. Thank you though. – Nyra May 23 '14 at 14:00
1

This should do the trick in a line

Dictionary<string, string> result = d.ToDictionary(p => p.Key,p=> p.Value.PadLeft(10, '0'));
Mohamed
  • 470
  • 3
  • 14
-1

Use a for loop instead of foreach. In a foreach you cannot modify the collection (in your care d) because you are iterating on it

Alexandru Chichinete
  • 1,166
  • 12
  • 23