0

I have a string like this:

var totalOrders = "Beans - 1\nMeat balls - 1\nBrown bread - 2\nBeans - 2\nBanana slice - 1\nSteak with rice - 1\nBrown bread - 1\n";

It's dynamically created, so this one is just for the sake of example. Numbers represent how many portions are ordered. I need to split it to dictionary by the name of food as a key and count how many portions are ordered which would be a value.

I've tried this for spliting the string, first by '\n' then by ' - ':

count = totalOrders.Split('\n').ToDictionary(item => item.Split(" - ")[0], item => int.Parse(item.Split(" - ")[1]));

but I get an error "cannot convert from string to char. I had to use double quotes, because " - " this has 3 chars (2 spaces and a dash) and it's not recognized as a char.

Also, I think the problem will be when I start adding food, because it will report that keys won't be unique, considering that food appears more than once. How to solve this?

EDIT:

When I try this:

string[] countOrders = totalOrders.Split('\n');
string[] parts1 = countOrders.Split(new string[] { " - " }, StringSplitOptions.None);

I get error at .Split

'string[]' does not contain a definition for 'Split' and no extension method 'Split' accepting a first argument of type 'string[]' could be found

and if I try this "string countOrders =" (so without []) I get

Cannot implicitly convert type 'string[]' to 'string'

I don't understand how am I suppose to split the string by '\n' and then to split it by " - ", when it gives me errors in both cases?

Servy
  • 202,030
  • 26
  • 332
  • 449
Mark West
  • 45
  • 6
  • Just looking you might need to add string split options remove empties to your split method call because you are getting an additional item on the end which has nothing in it. That entry could be the cause if your int.Parse exception. So your split call would look like this totalOrders.Split(new char[] { '\n' },StringSplitOptions.RemoveEmptyEntries) – Bearcat9425 Mar 30 '17 at 18:23
  • Brown Bread is also in there twice so you will get duplicate Key Exception. – Bearcat9425 Mar 30 '17 at 18:28
  • Answer below has how you can utilize split with multiple characters. I did add it due to his answer came before I could post it. – Bearcat9425 Mar 30 '17 at 18:33

3 Answers3

2

You need to split and get rid of empty entries.
You can split on '-', no need to split on " - "
Then, Group by and sum to get a total dictionary

Dictionary<string, int> count =
    totalOrders.Split(new[] {'\n'}, StringSplitOptions.RemoveEmptyEntries)
        .Select(item => item.Split(new[] {'-'}, StringSplitOptions.RemoveEmptyEntries))
        .Select(arg=> new {Key = arg[0].Trim(), Val=  int.Parse(arg[1].Trim())})
        .GroupBy(arg=>arg.Key)
        .ToDictionary(g => g.Key, g => g.Sum(arg=>arg.Val));
Ofir Winegarten
  • 9,215
  • 2
  • 21
  • 27
1

Here is a non linq option since it was requested by the OP, I for one would prefer the linq way however this yeilds the same result

 var totalOrders = "Beans - 1\nMeat balls - 1\nBrown bread - 2\nBeans - 2\nBanana slice - 1\nSteak with rice - 1\nBrown bread - 1\n";
 var DictionaryHolder = new Dictionary<string, int>();
 //Split initial string into array and remove empties
 string[] initialArray = totalOrders.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

        foreach (var item in initialArray)
        {
            // Get the string Key or Entree
            string key = item.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries)[0].Trim();
            //  Get the Count of Portions
            int count = int.Parse(item.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries)[1].Trim());

            // check if Dictionary has the key already if not add it
            if (!DictionaryHolder.ContainsKey(key))
            {
                DictionaryHolder.Add(key, count);
            }
            else
            {
                // If the dictionary already had that key increase portion count by amount ordered.
                DictionaryHolder[key] = DictionaryHolder[key] + count;
            }
        }
Bearcat9425
  • 1,580
  • 1
  • 11
  • 12
0

You have two questions.

Question 1:

How to split by multiple characters is answered here: https://stackoverflow.com/a/1254596/2654498. Code below is directly from there.

string input = "abc][rfd][5][,][.";
string[] parts1 = input.Split(new string[] { "][" },StringSplitOptions.None);

Question 2:

You will need to check the dictionary to see if the Food already exists as a key. If it does, then you need to simply update the value of that food. If it doesn't exist as a key, add it as a new item to your dictionary.

if (!foodDict.ContainsKey(food))
{
     foodDict.Add(food, qty);
}
else
{
     foodDict[food] += qty;
}
Community
  • 1
  • 1
Nick
  • 882
  • 2
  • 9
  • 31
  • @MarkWest No problem. Basically, just utilize the `ContainsKey` function. If it doesn't exist (`if` condition above, then add it since it's a new food item). If it exists (`else` condition above, then just update the value. – Nick Mar 30 '17 at 18:30