Index was outside the bounds of the array c#, morse converter - c#

I was trying to build a Morse converter, the following is a part of my code of c#, but when I run it it tells me index out of the bounds, could anyone fix it? I'm new for programming:)
private void BTNconvert_Click(object sender, EventArgs e)
{
string input = TBinput.Text;
string[] output=new string[input.Length];
for (int index=0;index<input.Length;index++)
{
index=input.IndexOf('a',index);
output[index]=".-";
}
for (int index = 0; index < input.Length; index++)
{
index = input.IndexOf('b', index);
output[index] = "-...";
}
LBcodes.Text = string.Join(" ",output);

The reason you're seeing this error is that IndexOf() will return a -1 value if the given search term is not found in the string, so when you try to set output[-1] you end up with an invalid index.

private void BTNconvert_Click(object sender, EventArgs e)
{
int index;
string input = TBinput.Text;
string[] output=new string[input.Length];
index = -1;
do{
index=input.IndexOf('a',index+1);
if(index==-1)break;
output[index]=".-";
}while(true);
index = -1;
do{
index=input.IndexOf('b',index+1);
if(index==-1)break;
output[index]="-...";
}while(true);
}
LBcodes.Text = string.Join(" ",output);
also if you are going to make these loops for all of the characters I would recommand you to do this:
private void BTNconvert_Click(object sender, EventArgs e)
{
int index;
char[] source1 = {'a','b','c',....,'z'} //replace ... with characters
string[] source2 = {".-","-...",....} //replace .... with Morse equivalents
string input = TBinput.Text;
string[] output=new string[input.Length];
for(int i=0;i<26;i++){
index = -1;
do{
index=input.IndexOf(source1[i],index+1);
if(index==-1)break;
output[index]=source2[i];
}while(true);
}
}
LBcodes.Text = string.Join(" ",output);

IndexOf() will return -1 if specified text not found in the input string. Your code will work fine only if you entering specified character in the text box. That's why your code works fine when you removed the second loop and enter all a's to text box.
In addition to that why you need to use 2 loops. You are doing the same thing in both loops.

If it were me, I would keep a Dictionary mapping of each character and it's corresponding morse string. This will make it easy to convert back and forth.
For example:
private static Dictionary<char, string> MorseMap = new Dictionary<char, string>
{
{'A', ".-"}, {'B', "-..."}, {'C', "-.-."}, {'D', "-.."},
{'E', "."}, {'F', "..-."}, {'G', "--."}, {'H', "...."},
{'I', ".."}, {'J', ".---"}, {'K', "-.-"}, {'L', ".-.."},
{'M', "--"}, {'N', "-."}, {'O', "---"}, {'P', ".--."},
{'Q', "--.-"}, {'R', ".-."}, {'S', "..."}, {'T', "-"},
{'U', "..-"}, {'V', "...-"}, {'W', ".--"}, {'X', "-..-"},
{'Y', "-.--"}, {'Z', "--.."},{'1', ".----"}, {'2', "..---"},
{'3', "...--"}, {'4', "....-"},{'5', "....."}, {'6', "-...."},
{'7', "--..."}, {'8', "---.."},{'9', "----."}, {'0', "-----"},
{'.', ".-.-.-"}, {',', "--..--"},{'?', "..--.."}, {'\'', ".----."},
{'!', "-.-.--"}, {'/', "-..-."},{'(', "-.--."}, {')', "-.--.-"},
{'&', ".-..."}, {':', "---..."},{';', "-.-.-."}, {'=', "-...-"},
{'+', ".-.-."}, {'-', "-....-"},{'_', "..--.-"}, {'"', ".-..-."},
{'$', "...-..-"}, {'#', ".--.-."}
};
Now, using the keys and values from this map, it's fairly easy to encode and decode to morse:
private static string ConvertToMorse(string input)
{
var morse = new StringBuilder();
foreach (var character in input)
{
var upperCaseChar = char.ToUpper(character);
if (MorseMap.ContainsKey(upperCaseChar))
{
morse.Append(MorseMap[upperCaseChar]);
}
else
{
// If there's no mapping for this character, just add it
morse.Append(character);
}
// Add a space between each morse string.
morse.Append(' ');
}
return morse.ToString().Trim();
}
private static string ConvertToAlpha(string morse)
{
var alpha = new StringBuilder();
// Split words on double-spaces so we can add single spaces back where needed
var morseCodeWords = morse.Split(new[] {" "}, StringSplitOptions.None);
foreach (var morseCodeWord in morseCodeWords)
{
var morseCodeStrings = morseCodeWord.Split(' ');
foreach (var morseCodeString in morseCodeStrings)
{
if (MorseMap.ContainsValue(morseCodeString))
{
alpha.Append(MorseMap.First(item => item.Value == morseCodeString).Key);
}
else
{
// If there's no mapping for the string, just add it
alpha.Append(morseCodeString);
}
}
// Add a space between each word
alpha.Append(' ');
}
return alpha.ToString();
}
Usage Example:
private static void Main()
{
var test = "This is my test string.";
var morseVersion = ConvertToMorse(test);
var alphaVersion = ConvertToAlpha(morseVersion);
Console.WriteLine("Original string ... {0}", test);
Console.WriteLine("Morse version ..... {0}", morseVersion);
Console.WriteLine("Alpha version ..... {0}", alphaVersion);
}

Related

Extract multiple substring in the same line

I'm trying to build a logparser but i'm stuck.
Right now my program goes trough multiple file in a directory and read all the file line by line.
I was able to identify the substring i was looking for "fct=" and extract the value next to the "=" using delimiter but i notice that when i have a line with more then one "fct=" it doesnt see it.
So i restart my code and i find a way to get the index position of all occurence of fct= in the same line using an extension method that put the index in a list but i dont see how i can use this list to get the value next to the "=" and using my delimiter.
How can i extract the value next to the "=" knowing the start position of "fct=" and the delimiter at the end of the wanted value?
I'm starting in C# so let me know if i can give you more information.
Thanks,
Here's an example of what i would like to parse:
<dat>FCT=10019,XN=KEY,CN=ROHWEPJQSKAUMDUC FCT=666</dat></logurl>
<dat>XN=KEY,CN=RTU FCT=4515</dat></logurl>
<dat>XN=KEY,CN=RT</dat></logurl>
I would like t retrieve 10019,666 and 4515.
namespace LogParserV1
{
class Program
{
static void Main(string[] args)
{
int counter = 0;
string[] dirs = Directory.GetFiles(#"C:/LogParser/LogParserV1", "*.txt");
string fctnumber;
char[] enddelimiter = { '<', ',', '&', ':', ' ', '\\', '\'' };
foreach (string fileName in dirs)
{
StreamReader sr = new StreamReader(fileName);
{
String lineRead;
while ((lineRead = sr.ReadLine()) != null)
{
if (lineRead.Contains("fct="))
{
List<int> list = MyExtensions.GetPositions(lineRead, "fct");
//int start = lineRead.IndexOf("fct=") + 4;
// int end = lineRead.IndexOfAny(enddelimiter, start);
//string result = lineRead.Substring(start, end - start);
fctnumber = result;
//System.Console.WriteLine(fctnumber);
list.ForEach(Console.WriteLine);
}
// affiche tout les ligne System.Console.WriteLine(lineRead);
counter++;
}
System.Console.WriteLine(fileName);
sr.Close();
}
}
// Suspend the screen.
System.Console.ReadLine();
}
}
}
namespace ExtensionMethods
{
public class MyExtensions
{
public static List<int> GetPositions(string source, string searchString)
{
List<int> ret = new List<int>();
int len = searchString.Length;
int start = -len;
while (true)
{
start = source.IndexOf(searchString, start + len);
if (start == -1)
{
break;
}
else
{
ret.Add(start);
}
}
return ret;
}
}
}
You could simplify your code a lot by using Regex pattern matching instead.
The following pattern: (?<=FCT=)[0-9]* will match any group of digits preceded by FCT=.
Try it out
This enables us to do the following:
string input = "<dat>FCT=10019,XN=KEY,CN=ROHWEPJQSKAUMDUC FCT=666</dat></logurl>...";
string pattern = "(?<=FCT=)[0-9]*";
var values = Regex.Matches(input, pattern).Cast<Match>().Select(x => x.Value);
I have tested this solution with your data, and it gives me the expected results (10019,666 and 4515)
string data = #"<dat>FCT=10019,XN=KEY,CN=ROHWEPJQSKAUMDUC FCT=666</dat></logurl>
<dat>XN=KEY,CN=RTU FCT=4515</dat></logurl>
<dat>XN=KEY,CN=RT</dat></logurl>";
char[] delimiters = { '<', ',', '&', ':', ' ', '\\', '\'' };
Regex regex = new Regex("fct=(.+)", RegexOptions.IgnoreCase);
var values = data.Split(delimiters).Select(x => regex.Match(x).Groups[1].Value);
values = values.Where(x => !string.IsNullOrWhiteSpace(x));
values.ToList().ForEach(Console.WriteLine);
I hope my solution will be helpful, let me know.
Below code is usefull to extract the repeated words with linq in text
string text = "Hi Naresh, How are you. You will be next Super man";
IEnumerable<string> strings = text.Split(' ').ToList();
var result = strings.AsEnumerable().Select(x => new {str = Regex.Replace(x.ToLowerInvariant(), #"[^0-9a-zA-Z]+", ""), count = Regex.Matches(text.ToLowerInvariant(), #"\b" + Regex.Escape(Regex.Replace(x.ToLowerInvariant(), #"[^0-9a-zA-Z]+", "")) + #"\b").Count}).Where(x=>x.count>1).GroupBy(x => x.str).Select(x => x.First());
foreach(var item in result)
{
Console.WriteLine(item.str +" = "+item.count.ToString());
}
As always, break down the porblem into smaller bits. See if the following methods help in any way. Tying it up to your code is left as an excercise.
private const string Prefix = "fct=";
//make delimiter look up fast
private static HashSet<char> endDelimiters =
new HashSet<char>(new [] { '<', ',', '&', ':', ' ', '\\', '\'' });
private static string[] GetAllFctFields(string line) =>
line.Split(new string[] { Prefix });
private static bool TryGetValue(string delimitedString, out string value)
{
var buffer = new StringBuilder(delimitedString.Length);
foreach (var c in delimitedString)
{
if (endDelimiters.Contains(c))
break;
buffer.Append(c);
}
//I'm assuming that no end delimiter is a format error.
//Modify according to requirements
if (buffer.Length == delimitedString.Length)
{
value = null;
return false;
}
value = buffer.ToString();
return true;
}
Something like :
class Program
{
static void Main(string[] args)
{
char[] enddelimiter = { '<', ',', '&', ':', ' ', '\\', '\'' };
var fct = "fct=";
var lineRead = "fct=value1,useless text fct=vfct=alue2,fct=value3";
var values = new List<string>();
int start = lineRead.IndexOf(fct);
while(start != -1)
{
start += fct.Length;
int end = lineRead.IndexOfAny(enddelimiter, start);
if (end == -1)
end = lineRead.Length;
string result = lineRead.Substring(start, end - start);
values.Add(result);
start = lineRead.IndexOf(fct, end);
}
values.ForEach(Console.WriteLine);
}
}
You can split the line by string[]
char[] enddelimiter = { '<', ',', '&', ':', ' ', '\\', '\'' };
while ((lineRead = sr.ReadLine()) != null)
{
string[] parts1 = lineRead.Split(new string[] { "fct=" },StringSplitOptions.None);
if(parts1.Length > 0)
{
foreach(string _ar in parts1)
{
if(!string.IsNullOrEmpty(_ar))
{
if(_ar.IndexOfAny(enddelimiter) > 0)
{
MessageBox.Show(_ar.Substring(0, _ar.IndexOfAny(enddelimiter)));
}
else
{
MessageBox.Show(_ar);
}
}
}
}
}

How do i loop through the string and find out how many words are there?

I need help with my problem:
Right now I have a WPF application with a form that includes a button and a textbox.
Also, I have an open file directory - that opens .cs and .txt files.
I need to loop through the string of those files and display the most common words in them, starting from the largest to the smallest.
For example, a string would be:
"The sun is bright. The sun is yellow".
Would return:
The = 2;
sun = 2;
is = 2;
bright = 1;
yellow = 1;
My code right as of now:
private void btn1_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog() { Filter = "Text Documents |*.cs;*.txt", ValidateNames = true, Multiselect = false };
if (ofd.ShowDialog() == true)
rtb.Text = File.ReadAllText(ofd.FileName);
string[] userText = rtb.Text.ToLower().Split(new char[] { ' ', ',', '=', '+', '}', '{', '\r', '\n', '(', ')', ';' }, StringSplitOptions.RemoveEmptyEntries);
var frequencies = new Dictionary<string, int>();
foreach (string word in userText) //search words in our array userText that we declared at the beginning.
{
}
}
I am not sure how to continue from here... Help is appreciated.
Using the example and expected output that you have provided for us, I was able to accomplish this by using .GroupBy along with creating an anonymous class.
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
// example string
var myString = "The sun is bright. The sun is yellow";
// split the string into an array based on space characters and the period
var stringArray = myString.Split(new char[] {' ', '.'}, StringSplitOptions.RemoveEmptyEntries);
// group the items in the array based on the value, then create an anonymous class with the properties `Word` and `Count`
var groupedWords = stringArray.GroupBy(x => x).Select(x => new { Word = x.Key, Count = x.Count() }).ToList();
// print the properties based on order of largest to smallest count to screen
foreach(var item in groupedWords.OrderByDescending(x => x.Count))
{
Console.WriteLine(item.Word + " = " + item.Count);
}
// Output
---------
// The = 2
// sun = 2
// is = 2
// bright = 1
// yellow = 1
}
}
Let me know if this helps!
I would go with #GTown-Coder 's approach as the easiest. But if you really just want to know how to implement the same code using a dictionary as in your sample...
private void btn1_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog() { Filter = "Text Documents |*.cs;*.txt", ValidateNames = true, Multiselect = false };
if (ofd.ShowDialog() == true)
rtb.Text = File.ReadAllText(ofd.FileName);
string[] userText = rtb.Text.ToLower().Split(new char[] { ' ', ',', '=', '+', '}', '{', '\r', '\n', '(', ')', ';' }, StringSplitOptions.RemoveEmptyEntries);
var frequencies = new Dictionary<string, int>();
foreach (string word in userText) //search words in our array userText that we declared at the beginning.
{
// Sample here
if (frequencies.Contains(word))
{
frequencies[word]++;
}
else
{
frequencies.Add(word,1);
}
}
foreach (var kvp in frequencies)
Console.WriteLine("Word: {0} \t Frequency: {1}",kvp.Key, kvp.Value);
}
This almost sounds like the original definition of a dictionary, so that might be a good place to start:
IDictionary<string, int> actualDictionary = new Dictionary<string, int>();
You can place words in the dictionary, and increment their count each time you find them.
IDictionary<string, int> actualDictionary = new Dictionary<string, int>();
foreach (string word in userText) //search words in our array userText that we declared at the beginning.
{
if (!actualDictionary.ContainsKey(word)) {
actualDictionary[word] = 0;
}
actualDictionary[word]++;
}
foreach(var thing in actualDictionary) {
Console.WriteLine(thing.Key + " " + thing.Value);
}
See a running example on .NET Fiddle.

Dictionary with multiple keys isn't working as expected

I'm making a console program where I've got multiple values mapped to dictionary keyLookup. I'm using if commands that use the key to output some console.writeline = ("stuff"); but it only works if I have the value and the key the same (in the dictionary). I don't know why this is. I've been mucking about with list and foreach and some variables trying to figure out what I've done wrong but even though it continues to work how it works now it still doesn't work how I want.
Also if I have a word in my console.readline(); that isn't in my dictionary the whole thing crashes. Which I don't want, and I'm not sure of why its doing that either as at some point it didn't. Also my mathFunction dictionary works just how I want my keyLookup dictionary to work. Though I think the difference is in how I'm using a list to cross reference through keyLookup.
class MainClass
{
public static string Line;
static string foundKey;
public static void Main (string[] args)
{
while (true)
{
if (Line == null)
{Console.WriteLine ("Enter Input"); }
WordChecker ();
}
}
public static void WordChecker()
{
string inputString = Console.ReadLine ();
inputString = inputString.ToLower();
string[] stripChars = { ";", ",", ".", "-", "_", "^", "(", ")", "[", "]",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "\n", "\t", "\r" };
foreach (string character in stripChars)
{
inputString = inputString.Replace(character, "");
}
// Split on spaces into a List of strings
List<string> wordList = inputString.Split(' ').ToList();
// Define and remove stopwords
string[] stopwords = new string[] { "and", "the", "she", "for", "this", "you", "but" };
foreach (string word in stopwords)
{
// While there's still an instance of a stopword in the wordList, remove it.
// If we don't use a while loop on this each call to Remove simply removes a single
// instance of the stopword from our wordList, and we can't call Replace on the
// entire string (as opposed to the individual words in the string) as it's
// too indiscriminate (i.e. removing 'and' will turn words like 'bandage' into 'bdage'!)
while ( wordList.Contains(word) )
{
wordList.Remove(word);
}
}
// Create a new Dictionary object
Dictionary<string, int> dictionary = new Dictionary<string, int>();
// Loop over all over the words in our wordList...
foreach (string word in wordList)
{
// If the length of the word is at least three letters...
if (word.Length >= 3)
{
// ...check if the dictionary already has the word.
if ( dictionary.ContainsKey(word) )
{
// If we already have the word in the dictionary, increment the count of how many times it appears
dictionary[word]++;
}
else
{
// Otherwise, if it's a new word then add it to the dictionary with an initial count of 1
dictionary[word] = 1;
}
}
List<string> dicList = new List<string>();
dicList = dictionary.Keys.ToList ();
Dictionary<string, string> keyLookup = new Dictionary<string, string>();
keyLookup["hey"] = "greeting";
keyLookup["hi"] = "greeting";
keyLookup["greeting"] = "greeting";
keyLookup["math"] = "math";
keyLookup["calculate"] = "math";
keyLookup["equation"] = "math";
foundKey = keyLookup[word];
List<string> keyList = new List<string>();
foreach (string keyWord in dicList)
{
if(keyWord == foundKey)
{keyList.Add (keyWord); }
}
foreach (string mKey in keyList)
{
if(mKey == "greeting")
{Greetings ();}
if (mKey == "math")
{Math ();}
}
}
}
public static void Math()
{
Console.WriteLine ("What do you want me to math?");
Console.WriteLine ("input a number");
string input = Console.ReadLine ();
decimal a = Convert.ToDecimal (input);
Console.WriteLine("Tell me math function");
string mFunction = Console.ReadLine();
Console.WriteLine ("tell me another number");
string inputB = Console.ReadLine();
decimal b = Convert.ToDecimal (inputB);
Dictionary<string, string> mathFunction = new Dictionary<string, string>();
mathFunction["multiply"] = "multiply";
mathFunction["times"] = "multiply";
mathFunction["x"] = "multiply";
mathFunction["*"] = "multiply";
mathFunction["divide"] = "divide";
mathFunction["/"] = "divide";
mathFunction["subtract"] = "subtract";
mathFunction["minus"] = "subtract";
mathFunction["-"] = "subtract";
mathFunction["add"] = "add";
mathFunction["+"] = "add";
mathFunction["plus"] = "add";
string foundKey = mathFunction[mFunction];
if (foundKey == "add")
{
Console.WriteLine (a + b);
}
else if (foundKey == "subtract")
{
Console.WriteLine (a - b);
}
else if (foundKey == "multiply")
{
Console.WriteLine (a * b);
}
else if (foundKey == "divide")
{
Console.WriteLine (a / b);
}
else
{
Console.WriteLine ("not a math");
}
}
public static void Greetings()
{
Console.WriteLine("You said hello");
}
}'
You should iterate through the dictionary differently (Dont use ToList-Function).
Try this instead:
foreach (KeyValuePair kvp (Of String, String) In testDictionary)
{
Debug.WriteLine("Key:" + kvp.Key + " Value:" + kvp.Value);
}
And your application is crashing if the word doesn't match, because of this code (You're not creating a new entry that way):
// Otherwise, if it's a new word then add it to the dictionary with an initial count of 1
dictionary[word] = 1;
EDIT: I was wrong about that dictionary[word] = 1 would not create a new element. It's perfectly fine like this.
foundKey = keyLookup[word];
If word doesn't exist in keyLookup then it will crash.
string foundKey = mathFunction[mFunction];
if mFunction doesn't exist in mathFunction then it will crash.
If you're trying to make this a "conversational" program, then the word look-up is the most important part. You don't use predicates or LINQ, both can make string functions extremely easy. Currently you use a Dictionary. Why not use Lists for each keyword?
List<string> GreetingKeywords;
GreetingKeywords.Add("hello"); // ...
List<string> MathKeywords;
MathKeywords.Add("math"); // ...
foreach (var word in dicList)
{
if (GreetingKeywords.Contains(word))
{ Greetings(); }
if (MathKeywords.Contains(word))
{ Maths(); }
}
I'd suggest you read up on predicate and List/Dictionary functions such as Find, IndexOf, etc. etc. That knowledge is invaluable to C#.

How to call function over

I have made a function which can replace the position of the chars if they are standing in my list
Code:
public string NoSimilarChar(string password)
{
var listOfSimilarCharacters = new Dictionary<string, string>();
listOfSimilarCharacters.Add("l", "i");
listOfSimilarCharacters.Add("1", "i");
listOfSimilarCharacters.Add("O", "0");
// Iterate through each character
for (int i = 0; i < password.Length; i++)
{
var currentCharacter = password[i].ToString();
// check if the current char exists in either the key or the value of the list of similar characters
if (listOfSimilarCharacters.Keys.Contains(currentCharacter) || listOfSimilarCharacters.Values.Contains(currentCharacter))
{
currentCharacter = currentCharacter.Remove(currentCharacter.Length - 1, 1) + ",";
}
}
return password;
}
Now i want to know how to load the function NoSimilarChar over when the characters is remove
i thought something like this:
if (listOfSimilarCharacters.Keys.Contains(currentCharacter) || listOfSimilarCharacters.Values.Contains(currentCharacter))
{
currentCharacter = currentCharacter.Remove(currentCharacter.Length - 1, 1) + ",";
NoSimilarChar(password);
}
but i think this is not good because he then stays in a loop.
///for replacing
foreach (KeyValuePair<string, string> item in listOfSimilarCharacters)
{
password = password.Replace(item.Key, item.Value);
}
///for removing
foreach (KeyValuePair<string, string> item in listOfSimilarCharacters)
{
if (password.IndexOf(item.Key) >= 0)
password = password.Remove(password.IndexOf(item.Key), 1);
}
try this simpler one
var charsThatCannotbeinUserPwd = new[] {'1', 'l', 'O', '0', 'i'};
// Iterate through each character
var builder = new StringBuilder();
for (int i = 0; i < password.Length; i++)
{
var currentCharacter = password[i];
if (!charsThatCannotbeinUserPwd.Any(x => x.Equals(currentCharacter)))
builder.Append(currentCharacter);
}
return builder.ToString();
It looks like you want to remove a set of characters from you password. If that is the case then you don't need to use a Dictionary. A Dictionary would make more sense if you wanted to replace one character with another. Additionally you do not need to use recursion here. I believe all you need is an array of the characters you want to remove and a simple loop to remove them.
public string NoSimilarChar(string password)
{
string[] charsToRemove = new string[] { "l", "i", "1", "0", "O" }
foreach (string charToRemove in charsToRemove)
{
password = password.Replace(charToRemove, "");
}
return password;
}
FYI: I've defined the array of characters as strings because you will want to replace the character with an empty string and there is no empty character.

Convert array of strings to Dictionary<string, int> c# then output to Visual Studio

I have an array of strings like so:
[0]Board1
[1]Messages Transmitted75877814
[2]ISR Count682900312
[3]Bus Errors0
[4]Data Errors0
[5]Receive Timeouts0
[6]TX Q Overflows0
[7]No Handler Failures0
[8]Driver Failures0
[9]Spurious ISRs0
just to clarify the numbers in the square brackets indicate the strings position in the array
I want to convert the array of strings to a dictionary with the string to the left of each number acting as the key, for example (ISR Count, 682900312)
I then want to output specific entries in the dictionary to a text box/table in visual studio (which ever is better) it would be preferable for the numbers to be left aligned.
excuse my naivety, I'm a newbie!
Pretty Simple. Tried and Tested
string[] arr = new string[] { "Board1", "ISR Count682900312", ... };
var numAlpha = new Regex("(?<Alpha>[a-zA-Z ]*)(?<Numeric>[0-9]*)");
var res = arr.ToDictionary(x => numAlpha.Match(x).Groups["Alpha"],
x => numAlpha.Match(x).Groups["Numeric"]);
string[] strings =
{
"Board1", "Messages232"
};
Dictionary<string, int> dictionary = new Dictionary<string, int>();
foreach (var s in strings)
{
int index = 0;
for (int i = 0; i < s.Length; i++)
{
if (Char.IsDigit(s[i]))
{
index = i;
break;
}
}
dictionary.Add(s.Substring(0, index), int.Parse(s.Substring(index)));
}
var stringArray = new[]
{
"[0]Board1",
"[1]Messages Transmitted75877814",
"[2]ISR Count682900312",
"[3]Bus Errors0",
"[4]Data Errors0",
"[5]Receive Timeouts0",
"[6]TX Q Overflows0",
"[7]No Handler Failures0",
"[8]Driver Failures0",
"[9]Spurious ISRs0"
};
var resultDict = stringArray.Select(s => s.Substring(3))
.ToDictionary(s =>
{
int i = s.IndexOfAny("0123456789".ToCharArray());
return s.Substring(0, i);
},
s =>
{
int i = s.IndexOfAny("0123456789".ToCharArray());
return int.Parse(s.Substring(i));
});
EDIT: If the numbers in brackets are not included in the strings, remove .Select(s => s.Substring(3)).
Here you go:
string[] strA = new string[10]
{
"Board1",
"Messages Transmitted75877814",
"ISR Count682900312",
"Bus Errors0",
"Data Errors0",
"Receive Timeouts0",
"TX Q Overflows0",
"No Handler Failures0",
"Driver Failures0",
"Spurious ISRs0"
};
Dictionary<string, int> list = new Dictionary<string, int>();
foreach (var item in strA)
{
// this Regex matches any digit one or more times so it picks
// up all of the digits on the end of the string
var match = Regex.Match(item, #"\d+");
// this code will substring out the first part and parse the second as an int
list.Add(item.Substring(0, match.Index), int.Parse(match.Value));
}

Categories