I have an object class "Character" with a hashtable inside of it for weapons. I'm just trying to print the weapon to the console when I print the character stats for approval, but having a hard time figuring out a simple way to do this.
Advs is the Character object array, if there's any information I forgot to include please let me know, first time posting. The i.weapons.value is what I'm trying to fix, everything else prints to console correctly, that gives me strange values that look like pointers to the hashtable on print.
private static void ChStats(Character[] Advs) {
foreach (Character i in Advs) {
Console.WriteLine("Name: {0}\nClass: {1}\nLevel: {2}\nHealth: {3}\nStrength: {4}\nIntellect: {5}\nAgility: {6}\nSanity: {7}\nWeapon: {8}\n",
i.name, i.characterClass, i.lvl, i.hlth, i.str, i.itl, i.agi, i.san, i.weapons.value);
}
as an addition, the hash table contains two values for each weapon wNme and dmg. The code below works, but seem so sloppy, hopefully there's a better way to accomplish this.
foreach (Character i in Advs) {
string[] weaponDesc = new string[10];
int n = 0;
foreach (Weapon w in i.weapons.Values)
{
weaponDesc[n++] = w.wNme;
}
// this version works but with extra commas
//Console.WriteLine("Name: {0}\nClass: {1}\nLevel: {2}\nHealth: {3}\nStrength: {4}\nIntellect: {5}\nAgility: {6}\nSanity: {7}\nWeapon: {8}\n",
// i.name, i.characterClass, i.lvl, i.hlth, i.str, i.itl, i.agi, i.san, string.Join(", ", weaponDesc));
// better but more complex
Console.WriteLine("Name: {0}\nClass: {1}\nLevel: {2}\nHealth: {3}\nStrength: {4}\nIntellect: {5}\nAgility: {6}\nSanity: {7}\nWeapon: {8}\n",
i.name, i.characterClass, i.lvl, i.hlth, i.str, i.itl, i.agi, i.san, string.Join(", ", weaponDesc.Where(s => !string.IsNullOrEmpty(s))));
Generics typed HashSet class is a better choice.
HashSet<Weapon> Weapons;
Weapons = new HashSet<Weapon>();
Weapons.Add(new Weapon()); // Assume this is created and populated elsewhere
StringBuilder SBText = new StringBuilder(64 + (Weapons.Count * 8)); // An approximation of the eventual string length
SBText.Append(#"Class, Level, etc...");
// Cryptic but compact Lync method (Not my favourite)
Weapons.Where(Wpn => !string.IsNullOrEmpty(Wpn.name)).ToList().ForEach(delegate (Weapon Wpn) { if (SBText.Length > 0) { SBText.Append(#", "); } SBText.Append(Wpn.name); });
// Explicit code method
foreach (Weapon Wpn in Weapons)
{
if (!string.IsNullOrEmpty(Wpn.name))
{
if (SBText.Length > 0) { SBText.Append(#", "); }
SBText.Append(Wpn.name);
}
}
Console.WriteLine(SBText.ToString());
Related
Is there an algorith or C# library to determine if a human name is correct or not and, if not, to find its nearest matching?
I found algorithms for string matching like the Levenshtein's distance algorithm, but all of them check the matching between one string and another, and i want to check the matching between one name and all the possible names in English (for example), to check if the name was wrongly written.
For example:
Someone inserts the name "Giliam" while it should be "william". I want to know if there are any algorithm (or group of them) to detect the error and propose a correction.
All solutions that come to my mind involves the implementation of a huge human name's dictionary and use it to check for the correctness of each input name matching one by one... And it sounds terrorific performace to me, so i want to ask for a better approach.
Thanks.
What you are in effect asking is how to create a spell checker with a given dictionary. One way to do this that doesn't involve looking up and testing every possible entry in a list is to do the inverse of the problem: Generate a list of possible permutations from the user input, and test each one of those to see if they're in a list. This is a much more manageable problem.
For instance, you could use a function like this to generate each possible permutation that one "edit" could get from a given word:
static HashSet<string> GenerateEdits(string word)
{
// Normalize the case
word = word.ToLower();
var splits = new List<Tuple<string, string>>();
for (int i = 0; i < word.Length; i++)
{
splits.Add(new Tuple<string, string>(word.Substring(0, i), word.Substring(i)));
}
var ret = new HashSet<string>();
// All cases of one character removed
foreach (var cur in splits)
{
if (cur.Item2.Length > 0)
{
ret.Add(cur.Item1 + cur.Item2.Substring(1));
}
}
// All transposed possibilities
foreach (var cur in splits)
{
if (cur.Item2.Length > 1)
{
ret.Add(cur.Item1 + cur.Item2[1] + cur.Item2[0] + cur.Item2.Substring(2));
}
}
var letters = "abcdefghijklmnopqrstuvwxyz";
// All replaced characters
foreach (var cur in splits)
{
if (cur.Item2.Length > 0)
{
foreach (var letter in letters)
{
ret.Add(cur.Item1 + letter + cur.Item2.Substring(1));
}
}
}
// All inserted characters
foreach (var cur in splits)
{
foreach (var letter in letters)
{
ret.Add(cur.Item1 + letter + cur.Item2);
}
}
return ret;
}
And then exercise the code to see if a given user input can be easily convoluted to one of these entries. Finding the best match can be done by weighted averages, or simply by presenting the list of possibilities to the user:
// Example file from:
// https://raw.githubusercontent.com/smashew/NameDatabases/master/NamesDatabases/first%20names/all.txt
string source = #"all.txt";
var names = new HashSet<string>();
using (var sr = new StreamReader(source))
{
string line;
while ((line = sr.ReadLine()) != null)
{
names.Add(line.ToLower());
}
}
var userEntry = "Giliam";
var found = false;
if (names.Contains(userEntry.ToLower()))
{
Console.WriteLine("The entered value of " + userEntry + " looks good");
found = true;
}
if (!found)
{
// Try edits one edit away from the user entry
foreach (var test in GenerateEdits(userEntry))
{
if (names.Contains(test))
{
Console.WriteLine(test + " is a possibility for " + userEntry);
found = true;
}
}
}
if (!found)
{
// Try edits two edits away from the user entry
foreach (var test in GenerateEdits(userEntry))
{
foreach (var test2 in GenerateEdits(test))
{
if (names.Contains(test))
{
Console.WriteLine(test + " is a possibility for " + userEntry);
found = true;
}
}
}
}
kiliam is a possibility for Giliam
liliam is a possibility for Giliam
viliam is a possibility for Giliam
wiliam is a possibility for Giliam
Of course, since you're talking about human names, you had, at best, make this a suggestion, and be very prepared for odd spellings, and spellings of things you've never seen. And if you want to support other languages, the implementation of GenerateEdits gets more complex as you consider what counts for a 'typo'
I have a text file full of strings, one on each line. Some of these strings will contain an unknown number of "#" characters. Each "#" can represent the numbers 1, 2, 3, or 4. I want to generate all possible combinations (permutations?) of strings for each of those "#"s. If there were a set number of "#"s per string, I'd just use nested for loops (quick and dirty). I need help finding a more elegant way to do it with an unknown number of "#"s.
Example 1: Input string is a#bc
Output strings would be:
a1bc
a2bc
a3bc
a4bc
Example 2: Input string is a#bc#d
Output strings would be:
a1bc1d
a1bc2d
a1bc3d
a1bc4d
a2bc1d
a2bc2d
a2bc3d
...
a4bc3d
a4bc4d
Can anyone help with this one? I'm using C#.
This is actually a fairly good place for a recursive function. I don't write C#, but I would create a function List<String> expand(String str) which accepts a string and returns an array containing the expanded strings.
expand can then search the string to find the first # and create a list containing the first part of the string + expansion. Then, it can call expand on the last part of the string and add each element in it's expansion to each element in the last part's expansion.
Example implementation using Java ArrayLists:
ArrayList<String> expand(String str) {
/* Find the first "#" */
int i = str.indexOf("#");
ArrayList<String> expansion = new ArrayList<String>(4);
/* If the string doesn't have any "#" */
if(i < 0) {
expansion.add(str);
return expansion;
}
/* New list to hold the result */
ArrayList<String> result = new ArrayList<String>();
/* Expand the "#" */
for(int j = 1; j <= 4; j++)
expansion.add(str.substring(0,i-1) + j);
/* Combine every expansion with every suffix expansion */
for(String a : expand(str.substring(i+1)))
for(String b : expansion)
result.add(b + a);
return result;
}
I offer you here a minimalist approach for the problem at hand.
Yes, like other have said recursion is the way to go here.
Recursion is a perfect fit here, since we can solve this problem by providing the solution for a short part of the input and start over again with the other part until we are done and merge the results.
Every recursion must have a stop condition - meaning no more recursion needed.
Here my stop condition is that there are no more "#" in the string.
I'm using string as my set of values (1234) since it is an IEnumerable<char>.
All other solutions here are great, Just wanted to show you a short approach.
internal static IEnumerable<string> GetStrings(string input)
{
var values = "1234";
var permutations = new List<string>();
var index = input.IndexOf('#');
if (index == -1) return new []{ input };
for (int i = 0; i < values.Length; i++)
{
var newInput = input.Substring(0, index) + values[i] + input.Substring(index + 1);
permutations.AddRange(GetStrings(newInput));
}
return permutations;
}
An even shorter and cleaner approach with LINQ:
internal static IEnumerable<string> GetStrings(string input)
{
var values = "1234";
var index = input.IndexOf('#');
if (index == -1) return new []{ input };
return
values
.Select(ReplaceFirstWildCardWithValue)
.SelectMany(GetStrings);
string ReplaceFirstWildCardWithValue(char value) => input.Substring(0, index) + value + input.Substring(index + 1);
}
This is shouting out loud for a recursive solution.
First, lets make a method that generates all combinations of a certain length from a given set of values. Because we are only interested in generating strings, lets take advantage of the fact that string is immutable (see P.D.2); this makes recursive functions so much easier to implement and reason about:
static IEnumerable<string> GetAllCombinations<T>(
ISet<T> set, int length)
{
IEnumerable<string> getCombinations(string current)
{
if (current.Length == length)
{
yield return current;
}
else
{
foreach (var s in set)
{
foreach (var c in getCombinations(current + s))
{
yield return c;
}
}
}
}
return getCombinations(string.Empty);
}
Study carefully how this methods works. Work it out by hand for small examples to understand it.
Now, once we know how to generate all possible combinations, building the strings is easy:
Figure out the number of wildcards in the specified string: this will be our combination length.
For every combination, insert in order each character into the string where we encounter a wildcard.
Ok, lets do just that:
public static IEnumerable<string> GenerateCombinations<T>(
this string s,
IEnumerable<T> set,
char wildcard)
{
var length = s.Count(c => c == wildcard);
var combinations = GetAllCombinations(set, length);
var builder = new StringBuilder();
foreach (var combination in combinations)
{
var index = 0;
foreach (var c in s)
{
if (c == wildcard)
{
builder.Append(combination[index]);
index += 1;
}
else
{
builder.Append(c);
}
}
yield return builder.ToString();
builder.Clear();
}
}
And we're done. Usage would be:
var set = new HashSet<int>(new[] { 1, 2, 3, 4 });
Console.WriteLine(
string.Join("; ", "a#bc#d".GenerateCombinations(set, '#')));
And sure enough, the output is:
a1bc1d; a1bc2d; a1bc3d; a1bc4d; a2bc1d; a2bc2d; a2bc3d;
a2bc4d; a3bc1d; a3bc2d; a3bc3d; a3bc4d; a4bc1d; a4bc2d;
a4bc3d; a4bc4d
Is this the most performant or efficient implementation? Probably not but its readable and maintainable. Unless you have a specific performance goal you are not meeting, write code that works and is easy to understand.
P.D. I’ve omitted all error handling and argument validation.
P.D.2: if the length of the combinations is big, concatenting strings inside GetAllCombinations might not be a good idea. In that case I’d have GetAllCombinations return an IEnumerable<IEnumerable<T>>, implement a trivial ImmutableStack<T>, and use that as the combination buffer instead of string.
so I'm having trouble with the program recognizing the values of my array elements (The name 'a' does not exist in the current context) , plus i can't get line.split to work(I need it to read the next element after the ',' and it needs to loop for all books (it's a library program). Lastly i can't figure out how to change the "10" (i put the number at random, so it doesn't show me an error) in my for loop, so that the program stops after it read all the info from .txt. Here's the code:
EDIT : It doesn't show any more errors, it just crashes now. :(
using System;
using System.IO;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
foreach (string line in File.ReadAllLines(#"Duomenys.txt"))
{
string[] a = line.Split(',');
int ISBN = int.Parse(a[0]);
string BookName = a[1];
string Author = a[2];
string Genre = a[3];
string Publisher = a[4];
int PublishYear = int.Parse(a[5]);
int PageNumber = int.Parse(a[6]);
Console.WriteLine(PublishYear);
Console.WriteLine();
Console.ReadKey();
}
}
public void BookWithTheMostPages(int[] a)
{
int maxPages = 0;
string[] lines = File.ReadAllText(#"Duomenys.txt").Split('\n');
foreach (string line in lines)
{
{
Console.ReadLine();
if (a[6] > maxPages)
{
maxPages = a[6];
Console.WriteLine("Storiausios knygos pavadinimas: {0} , jos autorius(-ė): {1}", a[1], a[2]);
}
}
}
}
public void Publish(string[] a)
{
if (!File.Exists(#"Technologija.csv"))
File.Create(#"Technologija.csv").Dispose();
using (StreamWriter streamwrite = new StreamWriter(File.OpenWrite(#"Technologija.csv")))
{
if (a[2] == "Technologija")
{
streamwrite.WriteLine("\n ISBN : {0}, Pavadinimas: {1}, Autorius: {2}, Tipas: {3}, Leidykla: {4}, Išleidimo Metai: {5}, Puslapių skaičius: {6}", a[0], a[1], a[2], a[3], a[4], a[5], a[6]);
}
}
}
public void Output(string[] a)
{
if (!File.Exists(#"Autoriai.csv"))
File.Create(#"Autoriai.csv").Dispose();
using (StreamWriter streamWriter = new StreamWriter(File.OpenWrite(#"Autoriai.csv")))
{
streamWriter.WriteLine("\n{0}", a[2]);
}
}
public void Publishyear(string[] a)
{
if (a[5] == "2014")
{
for (int j = 1; j <= 5; j++)
Console.WriteLine("\nKnygos ISBN: {0}, Pavadinimas {1}, Autorius {2}", a[0], a[1], a[2]);
}
}
}
}
Here's the .txt example:
9781408855669, Harry Potter and the Chamber of Secrets, Joanne K Rowling, Apysaka, Bloomsbury Publishing PLC, 1998, 270. (It's one line)
a and line are scoped to the static Main method (well, actually a is defined twicein Main, which isn't legal). They do not exist outside of there, unless you make them available, either by passing them in as parameters, or by making them available via fields. You should probably:
come up with more meaningful names; a will not help you
pass the value in as a parameter (IMO this would be cleaner than fields, but fields would work too)
decide whether you are working in instance or static context - at the moment you have both, but never instantiate an object, so you won't be able to call any of the methods
Note that the using and foreach should not be terminated like that ; you probably meant:
foreach (string line in File.ReadAllLines(#"Duomenys.txt"))
{
string[] a = line.Split(',');
...
}
(no need for the using / StreamReader)
'a' only exists in the main function. Like Marc said, you'll want to pass in 'a' as a parameter if you're using it in a different function.
So first line of the function:
public void BookWithTheMostPages() {
}
Should be:
public void BookWithTheMostPages(string[] a)
And should be called in the main function like this:
BookeWithTheMostPages(a);
That-a-ways the function "knows" what 'a' is.
Also, I notice that you're not telling your Main function to run any of the functions you wrote. The program runs everything inside the Main function, not just everything in the Main.cs file. So your 'Publishyear', 'Output', 'Publish', and 'BookWithTheMostPages' function simply aren't running.
Now in regards to your Split function not working here's 2 things:
You have already have something name 'a' in your program, you cannot name another variable by the same name. Make sense?
You must 'Split' into another array, since Split returns a series of strings
So it should look like this:
string[] splitLine = line.split(',');
Also these to lines are not correct:
int PublishYear = Convert.ToInt32(a[5]);
int PageNumber = Convert.ToInt32(a[6]);
If you're wanting to have the 'PublishYear' and 'PageNumber' functions to return an int, they cannot be void functions.
public int Publishyear() {
/*Write your code in here*/
return year;
}
Then later you can use the Function like this to get a value.
int i = Publishyear();
Same goes for your 'PageNumber' Function.
There are still a lot of little errors in the program I haven't mentioned and it would take forever to write down everyone with an explination, but for a beginner like yourself take it piece by piece. Follow a guideline like this:
Write down what the program is supposed to do on paper.
Write a small portion of code (couple lines)
Test it.
Repeat steps 2 and 3 until finished.
One last thing, get in the habit of naming your variables with more descriptive names. 'a' doesn't let a reader know at a glance what 'a' is. Write code that is easy for other people to read. I know at the beginning programming can seems very hard and confusing, but keep at it, don't give up. And little by little you'll get this whole programming things figured out.
Cheers!
Alright so first of all, remove the
using (StreamReader dn = new StreamReader(#"Duomenys.txt"));
if you are not using it. If you are reading the file with File.ReadAllLines you are not going to need it. Also, you are not using your foreach loop correctly. The way you want to go would be something like this:
foreach (string line in File.ReadAllLines(#"Duomenys.txt"))
{
string[] a = line.split(',');
int ISBN = Convert.ToInt32(a[0]);
string BookName = a[1];
string Author = a[2];
string Genre = a[3];
string Publisher = a[4];
int PublishYear = Convert.ToInt32(a[5]);
int PageNumber = Convert.ToInt32(a[6]);
}
What I fixed aswell is that you first create a string array named a, but then create a normal string named a which does not work. Also no need to set a size for the array, string.Split() does this automatically.
EDIT: To loop the file lines, assuming they are seperated by line terminators, you could do this:
string[] lines = File.ReadAllText(filename).Split('\n');
// '\n' as the regular line terminator
foreach (string line in lines)
{
// Your other code ...
My code is currently busted and I am aware of this. I'm working one one part at a time and I have hit two stumbling blocks which I'm hoping to find help here in regards too.
I am trying to address my formatting issue with this question here.
With the code below, i read in a text file using StreamReader, and the selections come in all on the same line as I want them too seperated by a BAR ("|"). Unfortunately, the bar prints at the end of each word, not actually 'between' each word. I don't want the last bar to print. I know i could cheat and add a bar to the font with a Console.Write("|") but that would be cheating in my mind - i wouldn't really be printing/displaying a bar between the words as I was trying to make a more elegant console selection.
This is just something I'm doing to learn and is not part of our assignment, but i like to push myself when I can. I am very very new to attempting to code, I am a complete newb, please assume I know nothing and please know all help is very much appreciated.
THIS IS MY CODE THUS FAR:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;// Needed for Streaming...
using System.IO;// Needed for Streaming...
namespace a090___StreamReader_DictionarySearch
{
class Program
{
private const String FILE_NAME = "dictionary.txt";//establish text file instance
public void Play()
{
do
{
DisplayTitle();
List<Listing> items = LoadListings();//create a list of WordDef objects
int count = 0;
foreach (Listing myListing in items)//read in items from file
{
//Console.WriteLine(myListing.GetName() + ": " + myListing.GetDefinition());
Console.Write(myListing.GetName());
if (count != items.Count - 1)
{
Console.Write(" | ");
}
count++;
}
DisplayText("\n\nPlease enter a word from the selections about to see it's definition");// Nice use of PROMPT
String userSelection = Console.ReadLine().ToLower();//Capture input
/// What are we trying to do?
/// Collect value entered for comparison - chek!
///
/// Compare value entered against list (Does value match to name?)
/// IF value matches print description
/// if value does not match(Else), state no match
//if (userSelection == Listing.name)
//{Console.WriteLine("You selected: " + userSelection() +
// "\nWhich Means: " + Listing.GetDefinition());}
//else{Console.WriteLine("I'm sorry, I don't have a match for that.");}
} while (PlayAgain());
Salutation();
}
//ToolBox -- my program specific tools
public List<Listing> LoadListings()//load entries display as list
{
StreamReader fileIn = new StreamReader(FILE_NAME);
List<Listing> entry = new List<Listing>();
//loop through every line of the file
while (!fileIn.EndOfStream)
{
String line = fileIn.ReadLine();
String[] pieces = line.Split(':');
if (pieces.Length < 1) continue;//error handling - set to length of text items
Listing myListing = new Listing(pieces[0], pieces[1]);
entry.Add(myListing);
}
fileIn.Close(); return entry;
}
//MaxBox -- my useful tools
public void DisplayText(String StringNameIs)
{ Console.WriteLine(StringNameIs); }//Where are we?
public Boolean PlayAgain()
{
Console.Write("\n\nDo you select again? (y)es or (n)o: ");
String command = Console.ReadLine().ToLower();
if (command == "y" || command == "yes") return true;
return false;
}
public void Salutation()
{ Console.Clear(); Console.WriteLine("Ti Do - oh - oh Ti Do -- So Do!"); } //The last line from the 'do-re-mi' song from the Sound of Music
public void DisplayTitle()
{ Console.Clear(); Console.WriteLine(">>>-- A Dictionary of Sounds --<<< \n"); } //Announce Our Program
static void Main(string[] args)
{
Program DictionaryLookup = new Program();
DictionaryLookup.Play();
Console.Read();
}
}
}
Please note: I have searched StackOverflow, GOOGLE, BING, MS' resources, et al. for an answer i can understand with my limited skills/understanding. I've also been working on this for a few hours. Please help.
You're looking for string.Join. Replace the whole foreach loop
foreach (Listing myListing in items)//read in items from file
{
//Console.WriteLine(myListing.GetName() + ": " + myListing.GetDefinition());
Console.Write(myListing.GetName() + " | ");
}
with
Console.Write(string.Join(" | ", items.Select(x => x.GetName())));
Alternatively, you could try a writing a backspace to the console.
Edit: As noted in the comments, you'd need to print a space char over the last pipe.
Console.Write("\b \b");
You may convert List of objects to array of object property and cast it to a string with delimeter:
string str = String.Join(" | ", items.Select(x => x.GetName()).ToArray());
try something like this...
var items = LoadListings();//create a list of WordDef objects
int i = 1;
var sw = new StringBuilder();
foreach(var myListing in items)
{
sw.AppendFormat("{0}", myListing.GetName() + "|");
if (i=items.Count)
{
sw.Replace("|", "", i,i);
}else
{ i++; }
}
//Console.WriteLine(myListing.GetName() + ": " + myListing.GetDefinition());
Console.Write(sw);
List<Listing> items = LoadListings(); //create a list of WordDef objects
int checklast = 0;
foreach (Listing myListing in items) //read in items from file
{
if (checklast == items.Count-1)
{
Console.Write(myListing.GetName());
}
else
{
//Console.WriteLine(myListing.GetName() + ": " + myListing.GetDefinition());
Console.Write(myListing.GetName() + " | ");
}
++checklast;
}
You can use the lazy method by checking when the last item will come so you make sure won't add BAR at the end.
I am new to C# and I ran into the following problem (I have looked for a solution here and on google but was not successful):
Given an array of strings (some columns can possibly be doubles or integers "in string format") I would like to convert this array to an integer array.
The question only concerns the columns with actual string values (say a list of countries).
Now I believe a Dictionary can help me to identify the unique values in a given column and associate an integer number to every country that appears.
Then to create my new array which should be of type int (or double) I could loop through the whole array and define the new array via the dictionary. This I would need to do for every column which has string values.
This seems inefficient, is there a better way?
In the end I would like to do multiple linear regression (or even fit a generalized linear model, meaning I want to get a design matrix eventually) with the data.
EDIT:
1) Sorry for being unclear, I will try to clarify:
Given:
MAKE;VALUE ;GENDER
AUDI;40912.2;m
WV;3332;f
AUDI;1234.99;m
DACIA;0;m
AUDI;12354.2;m
AUDI;123;m
VW;21321.2;f
I want to get a "numerical" matrix with identifiers for the the string valued columns
MAKE;VALUE;GENDER
1;40912.2;0
2;3332;1
1;1234.99;0
3;0;0
1;12354.2;0
1;123;0
2;21321.2;1
2) I think this is actually not what I need to solve my problem. Still it does seem like an interesting question.
3) Thank you for the responses so far.
This will take all the possible strings which represent an integer and puts them in a List.
You can do the same with strings wich represent a double.
Is this what you mean??
List<int> myIntList = new List<int>()
foreach(string value in stringArray)
{
int myInt;
if(Int.TryParse(value,out myInt)
{
myIntList.Add(myInt);
}
}
Dictionary is good if you want to map each string to a key like this:
var myDictionary = new Dictionary<int,string>();
myDictionary.Add(1,"CountryOne");
myDictionary.Add(2,"CountryTwo");
myDictionary.Add(3,"CountryThree");
Then you can get your values like:
string myCountry = myDictionary[2];
But still not sure if i'm helping you right now. Do you have som code to specify what you mean?
I'm not sure if this is what you are looking for but it does output the result you are looking for, from which you can create an appropriate data structure to use. I use a list of string but you can use something else to hold the processed data. I can expand further, if needed.
It does assume that the number of "columns", based on the semicolon character, is equal throughout the data and is flexible enough to handle any number of columns. Its kind of ugly but it should get what you want.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication3
{
class StringColIndex
{
public int ColIndex { get; set; }
public List<string> StringValues {get;set;}
}
class Program
{
static void Main(string[] args)
{
var StringRepresentationAsInt = new List<StringColIndex>();
List<string> rawDataList = new List<string>();
List<string> rawDataWithStringsAsIdsList = new List<string>();
rawDataList.Add("AUDI;40912.2;m");rawDataList.Add("VW;3332;f ");
rawDataList.Add("AUDI;1234.99;m");rawDataList.Add("DACIA;0;m");
rawDataList.Add("AUDI;12354.2;m");rawDataList.Add("AUDI;123;m");
rawDataList.Add("VW;21321.2;f ");
foreach(var rawData in rawDataList)
{
var split = rawData.Split(';');
var line = string.Empty;
for(int i= 0; i < split.Length; i++)
{
double outValue;
var isNumberic = Double.TryParse(split[i], out outValue);
var txt = split[i];
if (!isNumberic)
{
if(StringRepresentationAsInt
.Where(x => x.ColIndex == i).Count() == 0)
{
StringRepresentationAsInt.Add(
new StringColIndex { ColIndex = i,
StringValues = new List<string> { txt } });
}
var obj = StringRepresentationAsInt
.First(x => x.ColIndex == i);
if (!obj.StringValues.Contains(txt)){
obj.StringValues.Add(txt);
}
line += (string.IsNullOrEmpty(line) ?
string.Empty :
("," + (obj.StringValues.IndexOf(txt) + 1).ToString()));
}
else
{
line += "," + split[i];
}
}
rawDataWithStringsAsIdsList.Add(line);
}
rawDataWithStringsAsIdsList.ForEach(x => Console.WriteLine(x));
Console.ReadLine();
/*
Desired output:
1;40912.2;0
2;3332;1
1;1234.99;0
3;0;0
1;12354.2;0
1;123;0
2;21321.2;1
*/
}
}
}