Parse text file into dictionary C# <string> <int> - c#

I have some code that is not working for parsing a text file to a dictionary...
Dictionary<string, int> dictDSDRecordsByValidCompCode = new Dictionary<string, int>(); // This dictionary will get rid of pipe delimited comp codes, get distinct, and keep cuont of how many DSD records per Comp Code
if (LineToStartOn.pInt > 0)
{
using (var sr = new StreamReader("\\rvafiler1\rdc\clients\sams\pif\DSD_Dictionary.txt"))
{
string line = null;
string key = null;
int value = 0;
// while it reads a key
while ((line = sr.ReadLine()) != null)
{
// add the key and whatever it
// can read next as the value
dictDSDRecordsByValidCompCode.Add(key, sr.ReadBlock);
dictDSDRecordsByValidCompCode.Add(value, sr.ReadBlock());
}
}
}
The last line is where it fails. It does not like the dictionay.Add(Line, sr.ReadBlock()) statements. Where am I going wrong?
I need to read in a string followed by an int,.

Your dictionary is declared as <string, int> but the second value you are adding is another string (from sr.ReadLine) I think you want a dictionary of <string, string>

Probably you want to make it as follows:
Where your key is line number
and your string is your line;
var dictDSDRecordsByValidCompCode = new Dictionary<int, string>(); // This dictionary will get rid of pipe delimited comp codes, get distinct, and keep cuont of how many DSD records per Comp Code
if (LineToStartOn.pInt > 0)
{
using (var sr = new StreamReader("\\rvafiler1\rdc\clients\sams\pif\DSD_Dictionary.txt"))
{
string line = null;
int lineNumber = 1;
// while it reads a key
while (!string.IsNullOrEmpty(line = sr.ReadLine()) )
{
// add the key and whatever it
// can read next as the value
dictDSDRecordsByValidCompCode.Add(lineNumber++, line);
}
}
}

I think this is what you're trying to do.
Using StreamReader to count duplicates?
Dictionary<string, int> firstNames = new Dictionary<string, int>();
foreach (string name in YourListWithNames)
{
if (!firstNames.ContainsKey(name))
firstNames.Add(name, 1);
else
firstNames[name] += 1;
}

If you are trying to add a line as a key and subsequent number from file as a value, it should look like this:
string key = null;
int value = 0;
// while it reads a key
while ((key = sr.ReadLine()) != null)
{
//read subsequent value
value = Convert.ToInt32(sr.ReadLine());
//put a key/value pair to dictionary
dictDSDRecordsByValidCompCode.Add(key, value);
}

Related

Need to check a key in a dictionary for the letters of a string

So I have a dictionary and need to check each key entry to see if it contains a series of letters in a string(lets call this LETTERS). If the key has any letters that LETTERS does not, or it has more of a letter than LETTERS has, it has to be removed.(LETTERS is not known beforehand)
This is the code involved
Dictionary<string, int> wordHolder = new Dictionary<string, int>();
string LETTERS = Console.ReadLine();
for (int i = 0; i < LETTERS.Count(); i++)
{
for (int j = 0; j < wordHolder.Count; j++)
{
}
}
I think i have it this time if you still need an answer
The below has 5 keys... 3 of which can not be created from the contents of "LETTERS".
Dictionary<string, int> wordHolder = new Dictionary<string, int>();
wordHolder.Add("CEFBA",1);
wordHolder.Add("ZDFEEG",2);
wordHolder.Add("TYHRFG", 3);
wordHolder.Add("FFFFBBDD", 4);
wordHolder.Add("PCDATTY", 5);
var keysToRemove = new List<string>();
string myLetters = "ABCDEF";
var myLettersArray = myLetters.ToCharArray();
foreach (var keyToCheck in wordHolder)
{
var keyCannotBeCreatedFromLetters = false;
var keyArray = keyToCheck.Key.ToCharArray();
foreach (var letterExists in
from keyLetterToCheck in keyArray
where !keyCannotBeCreatedFromLetters
select myLettersArray.Any(a => a == keyLetterToCheck)
into letterExists
where !letterExists select letterExists)
{
keysToRemove.Add(keyToCheck.Key);
keyCannotBeCreatedFromLetters = true;
}
}
foreach (var key in keysToRemove)
{
wordHolder.Remove(key);
}
It correctly identifies the 2nd, 3rd and 5th key as not creatable.
Below is the same logic but as foreach loops. I find this often useful so you can see whats happening internally.
foreach (var keyToCheck in wordHolder)
{
var keyCannotBeCreatedFromLetters = false;
var keyArray = keyToCheck.Key.ToCharArray();
foreach (var keyLetterToCheck in keyArray)
{
if (keyCannotBeCreatedFromLetters)
continue;
var letterExists = myLettersArray.Any(a => a == keyLetterToCheck);
if (letterExists) continue;
keysToRemove.Add(keyToCheck.Key);
keyCannotBeCreatedFromLetters = true;
}
}
Assuming you want to return any KeyValuePair which Key contains all letter inside LETTERS.
It would look like this:
// Assuming
// Dictionary<string, int> wordHolder = new Dictionary<string, int>(); // Something
// string LETTERS = ""; // Something
List<char> listLettersToHave = LETTERS.ToList();
Dictionary<string, int> researchResult = new Dictionary<string, int>();
foreach (KeyValuePair<string, int> pair in wordHolder)
{
List<char> listLettersYouHave = pair.Key.ToList();
bool ok = true;
// If not the same count go to next KeyValuePair
if (listLettersToHave.Count != listLettersYouHave.Count)
continue;
foreach (char toCheck in listLettersToHave)
{
// Search first occurence
if (!listLettersYouHave.Contains(toCheck))
{
ok = false;
break;
}
// Remove first occurence
listLettersYouHave.Remove(toCheck);
}
if (ok)
// If all letters contained then Add to result
researchResult.Add(pair.Key, pair.Value);
}
// if it's a function
// return researchResult;
It's an example and you can improve it but the idea is here.
EDIT :
If the dictionnary have for keys : abc, cbda, dca
An input of bac
The results key would be : abc
The solution is case sensitive but a .ToUpper() will solve the problem.
Using the previous example, if you want cbda to match you can remove the check on Count.

String array to a hashtable

I'm trying to fill a HashTable with a string array from a .txt file.
Currently, I am reading the .txt file from a directory, but canĀ“t fill the hashtable with a foreach loop.
I am getting the below:
Syntax error; value expected
Any help is much appreciated!
static Hashtable GetHashtable()
{
// Create and return new Hashtable.
Hashtable ht_rut = new Hashtable();
//Create a string from all the text
string rutcompleto = System.IO.File.ReadAllText(#"C:\datos rut.txt");
//create an array from the string split by ,
String[] rutArr = rutcompleto.Split(',');
//create a int key for the hashtable
int key = 1;
foreach (var item in rutArr)
{
ht_rut.Add(key,rutArr[]);
key = key + 1;
}
return ht_rut;
}
}
replace
ht_rut.Add(key,rutArr[]);
with
ht_rut.Add(key,item);
since you want to add the item instead of the whole array
you could also solve this with linq:
static Hashtable GetHashtable()
{
string[] rutcompleto = System.IO.File.ReadAllText(#"C:\datos rut.txt").Split(',');
return new Hashtable(Enumerable.Range(1, rutcompleto.Count()).ToDictionary(x => x, x => rutcompleto[x-1]));
}
rutArr[] is not a valid C# syntax, you need to use rutArr[index] or the iteration variable inside foreach item:
foreach (var item in rutArr)
{
ht_rut.Add(key, item);
key = key + 1;
}

TextFile to Dictionary

I have different input text files i need to parse them to dictionary .
The first line contains an integer, N, denoting the number of entries in the phone book.
Each of the N subsequent lines describes an entry in the form of 22 space-separated values on a single line. The first value is a friend's namename, and the second value is an 88-digit phone numberphone number.
After the N lines of phone book entries, there are an unknown number of lines of queries. Each line (query) contains a namename to look up, and you must continue reading lines until there is no more input.
Note: Names consist of lowercase English letters and are first names only.
Here are some sample inputs files .
Sample 1:
3 // total three entries
john
34087423764 //8 digit phone number
abc
34087423123 //8 digit phone number
dce
24589756
dce
abc
three
Sample 2:
100000
mued 40502760
reiw 53841370
gkry 12304153
clrb 52664724
rbrq
xxxx
nlvk
qfrw
negg
Now i wrote a program to handle it but i dont know how to handle sample 2 and how to identify the queries any ideas how to handle first line then other samples
Dictionary<String, long> phoneNumber = new Dictionary<string, long>();
int counter = 0;
int N = 0;
//Reading Input Sample Text File
String filePath = #"c:\TextFiles\textInput.txt";
String QueryFilePath= #"c:\TextFiles\Queries.txt";
if (File.Exists(filePath))
{
StreamReader sreamReader = new StreamReader(filePath);
string line = string.Empty;
long key = 0;
string value = string.Empty;
while ((line = sreamReader.ReadLine()) != null)
{
//value = Regex.Match(line, "\\d+").Value;
key = Convert.ToInt64(Regex.Match(line, "\\d+").Value);
value = (Regex.Match(line, "\\D+").Value).TrimStart(',');
phoneNumber.Add(Convert.ToString(value), Convert.ToInt64(key));
}
sreamReader.Close();
if (File.Exists(QueryFilePath))
{
StreamReader queryFileStreatReader = new StreamReader(QueryFilePath);
string lines = string.Empty;
string values = string.Empty;
while ((lines = queryFileStreatReader.ReadLine()) != null)
{
values = (Regex.Match(lines, "\\D+").Value).TrimStart(',');
if (phoneNumber.ContainsKey(values) == true)
{
Console.WriteLine("{0}={1}", values, phoneNumber[values]);
}
else
{
Console.WriteLine("Not found");
}
}
queryFileStreatReader.Close();
}
}
Console.ReadKey();
Finally i solved this problem infect it was not well described in problem statement created a lot of confusion .
class Solution {
public static Dictionary<String, string> phoneBook = new Dictionary<string, string>();
static void Main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution */
//string searchText = "sam";
Int32 N = Convert.ToInt32(Console.ReadLine());
string readData = "";
for (Int32 i = 0; i < N; i ++)
{
readData = Console.ReadLine();
if (readData.Trim().Contains(" "))
if (!phoneBook.ContainsKey(readData.Trim().Split(' ')[0]))
phoneBook.Add(readData.Trim().Split(' ')[0], readData.Trim().Split(' ')[1]);
}
while ((readData = Console.ReadLine()) != null)
SearchPhoneNumbers(readData.Trim());
}
public static void SearchPhoneNumbers(string searchQuery)
{
if (phoneBook.ContainsKey(searchQuery))
Console.WriteLine("{0}={1}", searchQuery, phoneBook[searchQuery]);
else
Console.WriteLine("Not found");
}
}

IDictionary<String, List<OpenXmlCompositeElement>> - get the List<OpenXmlCompositeElement>?

I'm working with Open XML & I have a IDictionary<String, List<OpenXmlCompositeElement>> structure. I want to work with the List part of the structure but this.map.Values tries to wrap it in an ICollection. How can I get the List part from my structure?
public List<OpenXmlCompositeElement> MapData()
{
//this does not work
return this.map.Values;
}
Since it is a dictionary, it expects you to tell from which key you want the value.
So this would be the code you need, where yourKey is the key you want to retrieve:
public List<OpenXmlCompositeElement> MapData()
{
return this.map["yourKey"];
}
If you have no interest in the key, and the dictionary is just a dictionary because the serializer says so, you could get the first item for example like this:
public List<OpenXmlCompositeElement> MapData()
{
return this.map.Values.First();
}
You can either loop through the dictionary and use the value you would like, or access the List directly using the key (in this case it's a string)
IDictionary<String, List<OpenXmlCompositeElement>> myDictionary;
List<OpenXmlCompositeElement> myList = myDictionary["myKey"];
Where myKey is available in the dictionary.
Alternatively you can loop through
foreach (var item in myDictionary)
{
var key = item.Key;
var value = item.Value
// You could then use `key` if you are unsure of what
// items are in the dictionary
}
Assuming this is your dictionary...
IDictionary<string, List<OpenXmlCompositeElement>> items = ...;
Get a specific List by key...
List<OpenXmlCompositeElement> list = items["key"];
Get the first list in the dictionary...
List<OpenXmlCompositeElement> list = items.Values.First();
Concatenate all lists in the dictionary into a single list...
List<OpenXmlCompositeElement> list = items.SelectMany(o => o).ToList();
foreach(KeyValuePair<string, List<OpenXmlCompositeElement>> kvp in IDictionary)
{
string key = kvp.key
List<OpenXmlCompositeElement> list = kvp.Value;
foreach(OpenXmlCompositeElement o in list)
{
Do anything you need to your List here
}
}
I am working with dictionaries as well, so here is a real example that I am currently working with:
foreach(KeyValuePair<string, List<DataRecords>> kvp in vSummaryResults)
{
string sKey = kvp.Key;
List<DataRecords> list = kvp.Value;
string[] vArr = sKey.Split(',');
int iTotalTradedQuant = 0;
double dAvgPrice = 0;
double dSumQuantPrice = 0;
double dQuantPrice = 0;
double dNumClose = 0;
foreach (DataRecords rec in list)
{
if(vSummaryResults.ContainsKey(sKey))
{
iTotalTradedQuant += rec.iQuantity;
dQuantPrice = rec.iQuantity * rec.dInputTradePrice;
dSumQuantPrice += dQuantPrice;
dAvgPrice = dSumQuantPrice / iTotalTradedQuant;
dNumClose = rec.dNumericClosingPrice;
}
else
{
vSummaryResults.Add(sKey, list);
//dNumClose = rec.dNumericClosingPrice;
}

Mapping from 2D array in C#

I want to use a 2-D array in C#, e.g:
string[,] a = new string[,]
{
{"aunt", "AUNT_ID"},
{"Sam", "AUNT_NAME"},
{"clozapine", "OPTION"},
};
My requirement is that when I pass "aunt" to this array I want to get corresponding AUNT_ID from the 2-D array.
As others have said, a Dictionary<string, string> would be better - and you can use a collection initializer to create it simply:
Dictionary<string, string> dictionary = new Dictionary<string, string>
{
{"ant", "AUNT_ID"},
{"Sam", "AUNT_NAME"},
{"clozapine", "OPTION"},
};
If you're confident that your key is in the dictionary, and you're happy for an exception to be thrown otherwise:
string value = dictionary[key];
or if it might not be:
string value;
if (dictionary.TryGetValue(key, out value))
{
// Use value here
}
else
{
// Key wasn't in dictionary
}
If you really need to use an array, if you can change it to a multidimensional array (string[][]), you can use:
// Will throw if there are no matches
var value = array.First(x => x[0] == key)[1];
Or again to be more circumspect:
var pair = array.FirstOrDefault(x => x[0] == key);
if (pair != null)
{
string value = pair[1];
// Use value here
}
else
{
// Key wasn't in dictionary
}
LINQ unfortunately doesn't work quite as well on rectangular arrays. It probably wouldn't be too hard to write a method to allow it to be treated "somewhat" like an array of arrays, admittedly...
Use Dictionary<string, string> for that:
Dictionary<string, string> arr = new Dictionary<string, string>();
arr.Add("ant", "AUNT_ID");
arr.Add("Sam", "AUNT_NAME");
arr.Add("clozapine", "OPTION");
string k = arr["ant"]; // "AUNT_ID"
The best option for you is to use Dictionary, but if you still wants to use 2D array, you may try the following
string[,] a = new string[,]
{
{"ant", "AUNT_ID"},
{"Sam", "AUNT_NAME"},
{"clozapine", "OPTION"},
};
string search = "ant";
string result = String.Empty;
for (int i = 0; i < a.GetLength(0); i++) //loop until the row limit
{
if (a[i, 0] == search)
{
result = a[i, 1];
break; //break the loop on find
}
}
Console.WriteLine(result); // this will display AUNT_ID
It looks rather like you want a dictionary:
Dictionary<string, string> a = new Dictionary<string, string>();
a.Add("ant", "AUNT_ID");
a.Add("Sam", "AUNT_NAME");
a.Add("clozapine", "OPTION");
string s = a["ant"]; // gets "AUNT_ID"
To check if a key exists in the dictionary:
if (a.ContainsKey("ant")) {
...
}
Or:
string s;
if (a.TryGetValue("ant", out s)) {
...
}
for (i=0; i<3; i++){
if (!String.Compare(a[i][0], string)){
stored_string= a[i][1];
}
}

Categories