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;
}
Related
The string I want to split is an array of strings.
the array contains strings like:
G1,Active
G2,Inactive
G3,Inactive
.
.
G24,Active
Now I want to store the G's in an array, and Active or Inactive in a different array. So far I have tried this which has successfully store all the G's part but I have lost the other part. I used Split fucntion but did not work so I have tried this.
int i = 0;
for(i = 0; i <= grids.Length; i++)
{
string temp = grids[i];
temp = temp.Replace(",", " ");
if (temp.Contains(' '))
{
int index = temp.IndexOf(' ');
grids[i] = temp.Substring(0, index);
}
//System.Console.WriteLine(temp);
}
Please help me how to achieve this goal. I am new to C#.
If I understand the problem correctly - we have an array of strings Eg:
arrayOfStrings[24] =
{
"G1,Active",
"G2,Inactive",
"G3,Active",
...
"G24,Active"
}
Now we want to split each item and store the g part in one array and the status into another.
Working with arrays the solution is to - traverse the arrayOfStrings.
Per each item in the arrayOfStrings we split it by ',' separator.
The Split operation will return another array of two elements the g part and the status - which will be stored respectively into distinct arrays (gArray and statusArray) for later retrieval. Those arrays will have a 1-to-1 relation.
Here is my implementation:
static string[] LoadArray()
{
return new string[]
{
"G1,Active",
"G2,Inactive",
"G3,Active",
"G4,Active",
"G5,Active",
"G6,Inactive",
"G7,Active",
"G8,Active",
"G9,Active",
"G10,Active",
"G11,Inactive",
"G12,Active",
"G13,Active",
"G14,Inactive",
"G15,Active",
"G16,Inactive",
"G17,Active",
"G18,Active",
"G19,Inactive",
"G20,Active",
"G21,Inactive",
"G22,Active",
"G23,Inactive",
"G24,Active"
};
}
static void Main(string[] args)
{
string[] myarrayOfStrings = LoadArray();
string[] gArray = new string[24];
string[] statusArray = new string[24];
int index = 0;
foreach (var item in myarrayOfStrings)
{
var arraySplit = item.Split(',');
gArray[index] = arraySplit[0];
statusArray[index] = arraySplit[1];
index++;
}
for (int i = 0; i < gArray.Length; i++)
{
Console.WriteLine("{0} has status : {1}", gArray[i] , statusArray[i]);
}
Console.ReadLine();
}
seems like you have a list of Gxx,Active my recomendation is first of all you split the string based on the space, which will give you the array previoulsy mentioned doing the next:
string text = "G1,Active G2,Inactive G3,Inactive G24,Active";
string[] splitedGItems = text.Split(" ");
So, now you have an array, and I strongly recommend you to use an object/Tuple/Dictionary depends of what suits you more in the entire scenario. for now i will use Dictionary as it seems to be key-value
Dictionary<string, string> GxListActiveInactive = new Dictionary<string, string>();
foreach(var singleGItems in splitedGItems)
{
string[] definition = singleGItems.Split(",");
GxListActiveInactive.Add(definition[0], definition[1]);
}
What im achiving in this code is create a collection which is key-value, now you have to search the G24 manually doing the next
string G24Value = GxListActiveInactive.FirstOrDefault(a => a.Key == "G24").Value;
just do it :
var splitedArray = YourStringArray.ToDictionary(x=>x.Split(',')[0],x=>x.Split(',')[1]);
var gArray = splitedArray.Keys;
var activeInactiveArray = splitedArray.Values;
I hope it will be useful
You can divide the string using Split; the first part should be the G's, while the second part will be "Active" or "Inactive".
int i;
string[] temp, activity = new string[grids.Length];
for(i = 0; i <= grids.Length; i++)
{
temp = grids[i].Split(',');
grids[i] = temp[0];
activity[i] = temp[1];
}
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;
}
The purpose of my program is to take a data txt file and edit it, and/or make additions and subtractions to it.
The text file format is like this:
Name|Address|Phone|# of people coming|isRSVP
The code I have seems to be doing it's job all the way up until I try to click one of the names within a listbox and it needs to search through the multidimensional array to pull information out and place within a set of textboxes where they can be edited. The problem is that the foreach loop I use gives me an out of bounds exception. I tried to do a step into debug to make sure the data is correct in the array and see the process. Everything seems to do correctly but for some reason in the conditional statement person[0]==listbox1.selectedIndex isn't returning true even though both are the same as I seen through the step into process. Any help would be greatly appreciated.
This is my code:
StringBuilder newFile = new StringBuilder();
static string txtList= "guest_list.txt";
static string[] file = File.ReadAllLines(txtList);
static int x = file.Count();
string[,] list = new string[x ,5];
public void loadGuestList()
{
int count2 = 0;
foreach (string line in file)
{
string[] sliced = line.Split('|');
int count = 0;
list[count2, count] = sliced[0];
count++;
list[count2, count] = sliced[1];
count++;
list[count2,count] = sliced[2];
count++;
list[count2,count]= sliced[3];
count++;
list[count2, count] = sliced[4];
count++;
listBox1.Items.Add(list[count2,0]);
count2++;
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (string person in list)
{
if ( person[0].ToString()==listBox1.SelectedItem.ToString())
{
addTxt.Text = char.ToString(person[1]);
textPhone.Text = char.ToString(person[2]);
textPeople.Text = char.ToString(person[3]);
if (person[4] == 'n' )
{
}
else
{
chkRSVP.Checked = true;
}
break;
}
}
}
The problem lies in this line:
foreach (string person in list)
The list is defined as being string[,] which when you for each over will do every element, not just the column of data. You really should do something such as:
for(int index = 0; index <= list.GetUpperBound(0); index++)
{
string slice1 = list[index, 0];
string slice2 = list[index, 1];
....
}
or switch to using a Dictionary<string, string[]>().
Try to use a "Person" object and override equals(). Right now you're trying to put your multidimensional array (list[0]) into a string, it'll give you a unwanted result. You should use list[0,0] instead.
In agreement with Adam Gritt, I tested the following code and it seemed to work:
using System;
namespace so_foreach_bounds
{
class MainClass
{
public static void Main (string[] args)
{
//System.Text.StringBuilder newFile = new System.Text.StringBuilder();
string txtList= "guest_list.txt";
string[] file = System.IO.File.ReadAllLines(txtList);
int x = file.Length;
System.Collections.Generic.List<string[]> list = new System.Collections.Generic.List<string[]> ();
foreach (string line in file)
{
string[] sliced = line.Split('|');
list.Add(sliced);
}
foreach (string[] person in list)
{
Console.WriteLine (String.Join(", ", person));
if (person[0] =="Gary")
{
string txtAdd = person[1];
string txtPhone = person[2];
string txtpeople = person[3];
if (person[4] == "n" )
{
}
else
{
bool has_resvped = true;
}
break;
}
}
}
}
}
The issue is how you are iterating over the 2d array. It is usually a better idea to create a "Person" class, than try to manage it via arrays though. Oh yes, and it's usually a good idea to check that a list box item is selected before attempting to use one of its members.
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);
}
parse the xml and form dictionary with same key for multiple values
Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>();
doc.Load(confidencethresholdFilePath + "\\input.xml");
// XmlNodeList nodes = doc.DocumentElement.SelectNodes("/root/file");
doc.Normalize();
XmlNodeList nList = doc.GetElementsByTagName("key");
for (int temp = 0; temp < nList.Count; temp++)
{
string keyvalue = "";
XmlNode nNode = nList.Item(temp);
List<String> main = new List<string>();
ArrayList arrayList = new ArrayList(main);
XmlElement ele = (XmlElement)nNode;
keyvalue = ele.GetAttribute("value");
for (int i = 0; i < ele.ChildNodes.Count; i++)
{
if (ele.ChildNodes[i].ChildNodes.Count == 1)
{
Double sec = Double.Parse(ele.ChildNodes[i].InnerText);
int seg = TimeToSegment(sec);
Console.WriteLine("" + seg);
main.Add(Convert.ToString(seg));
}
}
dictionary.Add(keyvalue, main);
}
I want to comapare with single value but it shows error
dictionary.ContainsValue(s.sname) invalid arguments
I am not sure what you want to check but if you are trying to match keys then do this:
dictionary.ContainsKey(s.sname);
Or you might try:
IEnumerable<KeyValuePair<string,List<string>>> ienKeyVals = dictionary.Where(x => x.Value.Contains(s.sname));
parse the xml and form dictionary with same key for multiple values
A dictionary cannot contain duplicate keys. Its not possible to add duplicate items to a Dictionary - an alternative is to use the Lookup class.
Enumerable.ToLookup Method
Creates a generic Lookup from an IEnumerable.