Hope this helps. I’m not sure it’s the best way to approach your problem, but it should help you to familiarise yourself with some of the options / see why some of the guys on here are advising against it. If you let us know more about what you’re trying to do we can better advise alternate approaches.
using System;
using System.Collections.Generic;
using System.Linq;
namespace StackOverflow.Demos
{
class Program
{
const string OutputFormat = "{0}: {1}";
public static void Main(string[] args)
{
new Program();
Console.WriteLine("Done");
Console.ReadKey();
}
public Program()
{
SortedDictionary<string, int> dic = new SortedDictionary<string, int>();
dic.Add("a", 1);
dic.Add("b", 2);
dic.Add("d", 2);
dic.Add("c", 1);
dic.Add("e", 1);
dic.Add("f", 3);
dic.Add("g", 4);
dic.Add("h", 2);
dic.Add("i", 2);
OutputByKeyAsc(dic);
OutputByKeyDesc(dic);
OutputByValueFrequency(dic);
}
void OutputByKeyAsc(SortedDictionary<string, int> dic)
{
Console.WriteLine("OutputByKeyAsc");
foreach (string key in dic.Keys)
{
Console.WriteLine(string.Format(OutputFormat, key, dic[key]));
}
}
void OutputByKeyDesc(SortedDictionary<string, int> dic)
{
Console.WriteLine("OutputByKeyDesc");
foreach (string key in dic.Keys.Reverse())
{
Console.WriteLine(string.Format(OutputFormat, key, dic[key]));
}
}
void OutputByValueFrequency(SortedDictionary<string, int> dic)
{
Console.WriteLine("OutputByValueFrequency");
IEnumerable<KeyValuePair<int,int>> values =
(
from sortedItem
in
(
from entry
in dic
group entry
by entry.Value
into result
select new KeyValuePair<int,int>(result.Key , result.Count())
)
orderby sortedItem.Value descending
select sortedItem
).ToArray();
foreach (KeyValuePair<int, int> value in values)
{
foreach (KeyValuePair<string, int> item in dic.Where<KeyValuePair<string, int>>(item => item.Value == value.Key))
{
Console.WriteLine(string.Format(OutputFormat, item.Key, string.Format(OutputFormat, item.Value, value.Value)));
}
}
}
}
}
Good luck / hope you’re enjoying c# so far.
EDIT
Based on the new info in your question here’s my attempt at a neater solution:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace StackOverflow.Demos
{
class Program
{
const string OutputFormat = "{0}: {1}";
public static void Main(string[] args)
{
new Program("Another great story and another great adventure.");
Console.WriteLine("Done");
Console.ReadKey();
}
public Program(string userInput)
{
//break string into words
IEnumerable<IGrouping<string, int>> words = Regex.Split(userInput, @"\W+").GroupBy(word => word.ToLowerInvariant(), word => 1); //nb converting word to lower case to avoid case sensitive comparisons in grouping - I can keep the original value(s) by replacing "word => 1" with "word => word" if needed
Console.WriteLine("\nWords in alphabetic order");
foreach (IGrouping<string, int> wordInfo in words.OrderBy(word => word.Key))
{
Console.WriteLine(string.Format(OutputFormat, wordInfo.Key,wordInfo.Count()));
}
Console.WriteLine("\nWords in descending alphabetic order");
foreach (IGrouping<string, int> wordInfo in words.OrderByDescending(word => word.Key))
{
Console.WriteLine(string.Format(OutputFormat, wordInfo.Key, wordInfo.Count()));
}
Console.WriteLine("\nWords by frequency (desc)");
foreach (IGrouping<string, int> wordInfo in words.OrderByDescending(word => word.Count()))
{
Console.WriteLine(string.Format(OutputFormat, wordInfo.Key, wordInfo.Count()));
}
}
}
}
EDIT
Here’s the same code with the functionality in a class and the output kept in the program:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace StackOverflow.Demos
{
class Program
{
const string OutputFormat = "{0}: {1}";
public static void Main(string[] args)
{
new Program("Another great story and another great adventure.");
Console.WriteLine("Done");
Console.ReadKey();
}
public Program(string userInput)
{
WordCounter myWordCounter = new WordCounter(userInput);
Console.WriteLine("\n**Alphabetical**");
foreach (KeyValuePair<string, int> wordInfo in myWordCounter.GetWordCountByWordAlphabeticalDesc())
{
Console.WriteLine(string.Format(OutputFormat,wordInfo.Key, wordInfo.Value));
}
Console.WriteLine("\n**Alphabetical Desc**");
foreach (KeyValuePair<string, int> wordInfo in myWordCounter.GetWordCountByWordAlphabeticalDesc())
{
Console.WriteLine(string.Format(OutputFormat, wordInfo.Key, wordInfo.Value));
}
Console.WriteLine("\n**Frequency Desc**");
foreach (KeyValuePair<string, int> wordInfo in myWordCounter.GetWordCountByFrequency())
{
Console.WriteLine(string.Format(OutputFormat, wordInfo.Key, wordInfo.Value));
}
}
}
public class WordCounter
{
string sentance;
IEnumerable<IGrouping<string, int>> words;
public WordCounter(string sentance)
{
this.sentance = sentance;
GetWords();
}
void GetWords()
{
this.words = Regex.Split(this.sentance, @"\W+").GroupBy(word => word.ToLowerInvariant(), word => 1);
}
public IEnumerable<KeyValuePair<string, int>> GetWordCountByWordAlphabetical()
{
return this.words.OrderBy(word => word.Key).Select(wordInfo => new KeyValuePair<string,int>(wordInfo.Key, wordInfo.Count()));
}
public IEnumerable<KeyValuePair<string, int>> GetWordCountByWordAlphabeticalDesc()
{
return this.words.OrderByDescending(word => word.Key).Select(wordInfo => new KeyValuePair<string, int>(wordInfo.Key, wordInfo.Count()));
}
public IEnumerable<KeyValuePair<string, int>> GetWordCountByFrequency()
{
return this.words.OrderByDescending(word => word.Count()).Select(wordInfo => new KeyValuePair<string, int>(wordInfo.Key, wordInfo.Count()));
}
}
}
5
solved Sorting a SortedDictionary of