Converting array to string looping issue - c#

I have a foreach loop going that is adding e-mail address to an array. At the end I join the array and push it into a string.
I have an issue when someone in the database has a blank email address it messes up my logic. Can someone help me fix this?
TestGuy1:
TestGuy2: 2#2.com
TestGuy3: 3#3.com
With the above information it creates a 3 length array and then turns it into a string like so:
sEmailList "2#2.com,3#3.com," string
Code:
DataTable GetUserReportsToChain = objEmployee.GetUserReportsToChain(LoginID, ConfigurationManager.AppSettings.Get("Connection").ToString());
int RowCount = GetUserReportsToChain.Rows.Count;
string[] aEmailList = new string[RowCount];
int iCounter = 0;
foreach (DataRow rRow in GetUserReportsToChain.Rows)
{
if (rRow["usrEmailAddress"].ToString() != "")
{
aEmailList[iCounter] = rRow["usrEmailAddress"].ToString();
iCounter++;
//String email = rRow["usrEmailAddress"].ToString();
}
}
string sEmailList = String.Join(",", aEmailList);
Any idea how I can fix this when the database has a blank value for e-mail?

All in one
var sEmailList = String.Join(",",
GetUserReportsToChain.Rows
.Cast<DataRow>()
.Select(m => m["usrEmailAddress"].ToString())
.Where(x => !string.IsNullOrWhiteSpace(x)));

You want to use List<string> instead of fixed size array. Or simple LINQ query that returns non-empty strings.
List<string> aEmailList = new List<string>();
foreach (DataRow rRow in GetUserReportsToChain.Rows)
{
if (!String.IsNullOrEmpty(rRow["usrEmailAddress"].ToString()))
{
aEmailList.Add(rRow["usrEmailAddress"].ToString());
}
}
string sEmailList = String.Join(",", aEmailList);

you can try with
String.Join(",", aEmailList.Where(s => !string.IsNullOrEmpty(s)));

You can change your if statement to:
if(!string.IsNullOrEmpty(rRow["usrEmailAddress"].ToString().Trim())

If you're using 3.0 or higher:
String.Join(",", aEmailList.Where(s => s.Trim() != ""));

Related

Issue with String.Split result

I trying to load 4 lines from text files:
email:pass
email1:pass1
email2:pass2
email3:pass3
I used string.split, however when I try to Add to the my List it doesn't load well.
Here what I tried:
List<string> AccountList = new List<string>();
Console.Write("File Location: ");
string FileLocation = Console.ReadLine();
string[] temp = File.ReadAllLines(FileLocation);
string[] tempNew = new string[1000];
int count = 0;
foreach(var s in temp)
{
AccountList.Add(s.Split(':').ToString());
count++;
}
I checked how it the strings look inside the lists and they were like this:
System.String[]
I want it to be like this:
AccountList[0] = email
AccountList[1] = pass
AccountList[2] = email1
AccountList[3] = pass1
String.Split yields a string array
foreach(var s in temp)
{
string[] parts = s.Split(':');
string email = parts[0];
string pass = parts[1];
...
}
To store these two pieces of information, create an account class:
public class Account
{
public string EMail { get; set; }
public string Password { get; set; }
}
Then declare your account list as List<Account>:
var accountList = new List<Account>();
foreach(var s in File.ReadLines(FileLocation))
{
string[] parts = s.Split(':');
var account = new Account { EMail = parts[0], Password = parts[1] };
accountList.Add(account);
}
Note that you don't need the temp variable. File.ReadLines reads the file as the loop progresses, so that the whole file needs not to be stored in memory. See: File.ReadLines Method (Microsoft Docs).
No need to count. You can get the count with
int count = accountList.Count;
This list will be easier to handle than a list interleaved with emails and passwords.
You can access an account by index
string email = accountList[i].EMail;
string pass = accountList[i].Password;
or
Account account = accountList[i];
Console.WriteLine($"Account = {account.EMail}, Pwd = {account.Password}");
From your expected result you can try this, string.Split will return a string array string[], which spite by your expect character.
then use the index to get string part.
foreach(var s in temp)
{
var arr = s.Split(':');
AccountList.Add(arr[0]);
AccountList.Add(arr[1]);
}
The problem is that Split returns a string array consisting of the parts of the string found between the split character(s), and you're treating it as a string.
Instead, your code can be simplified by taking the result of File.ReadAllLines (a string array) and using .SelectMany to select the resulting array from splitting each line on the : character (so you're selecting an array for each item in the array), and then calling ToList on the result (since you're storing it in a list).
For example:
Console.Write("Enter file location: ");
string fileLocation = Console.ReadLine();
// Ensure the file exists
while (!File.Exists(fileLocation))
{
Console.Write("File not found, please try again: ");
fileLocation = Console.ReadLine();
}
// Read all the lines, split on the ':' character, into a list
List<string> accountList = File.ReadAllLines(fileLocation)
.SelectMany(line => line.Split(':'))
.ToList();

C# separating data within a line from a text file

I have a data file
Name; LastName; EurosCents;
Name2; LastName2; EurosCents2;
(for example:
John; Smith; 4,20;
Josh; Peck; 6,50;
)
I need to read the data and then do some further work with it... Is there any way to read the lines and save them? As the only way to read from a text file is to read the entire line at once.
var lst = File.ReadAllLines(yourFilePath).Select(x => new
{
FirstName = x.Split(';')[0]
LastName = x.Split(';')[1]
Value = decimal.Parse(x.Split(';')[2])
}).ToList();
use
lst[7].FirstName = "xxx";
Console.WriteLine(lst[2].Value);
etc...
The File API provide multiple options for reading files. Below is a possible way to proceed:
foreach(var line in File.ReadAllLines(path))
{
var splitted = line.Split(';');
var name = splitted.ElementAtOrDefault(0);
var lastName = splitted.ElementAtOrDefault(1);
var cents = Decimal.Parse(splitted.ElementAtOrDefault(2));
}
Parsing will be very easy if you are comfortable using LINQ.
Below line can get you the file in a hierarchical structure.
var theselines = File.ReadLines(#"C:\Test.txt").Select(l => l.Split(','));
You can see the result of above line by debugging.
Later you can have any logic to get the required data from each line without using foreach loop.
var Data = theselines.Select(l => new
{
id = l.Where(t => t.Contains("01")).FirstOrDefault(),
Price = l.Where(t => t.Contains(",")).FirstOrDefault(),
Firstname= l[0],
lastname = l[1]
});
Providing that data itself (both names and cents) can't contain ; in order to get
items from the comma separated values you can just split:
var data = File
.ReadLines(#"C:\MyData.csv")
// .Skip(1) // <- in case you have caption to skip
.Select(line => line.Split(';'))
.Select(items => new {
Name = items[0],
LastName = items[1],
EuroCents = decimal.Parse(items[2]) //TODO: check type and its format
});
//.ToArray(); // <- if you want to materialize as, say, an array
Then you can use it
foreach (var item in data) {
if (item.EuroCents > 10) {
...
}
}
the simple code to read whole file is as follows
string[] test(string path)
{
System.IO.StreamReader sr = new System.IO.StreamReader(path);
string[] str = sr.ReadToEnd().Split(';');
sr.Close();
return str;
}

C# Convert List<object> to list<hashtable>

This is my first question here, so sorry for any wrong information or about my English.
I need to convert a List<Object> to List<Hashtable>
string IdsLista = string.Empty;
foreach (DataRow rows in ListaItensTransferencia.Rows)
{
IdsLista += Convert.ToString(rows["Id Bem"]) + ",";
}
string[] idsSelecionadosListaTransferencia = IdsLista.Split(',');
List<object> listaIdsSelecionadosListTransferencia = new List<object>(idsSelecionadosListaTransferencia.Length);
listaIdsSelecionadosListTransferencia.AddRange(idsSelecionadosListaTransferencia);
wuc_itensTransferencia.checkBoxGrid = listaIdsSelecionadosListTransferencia;
//v this is the list<hashtable> v this is the list<object>
wuc_itensTransferencia.ItensSelecionados = listaIdsSelecionadosListTransferencia;
How do I do this ?
Instead of putting data into list of object, put directly into list of hashtable. Why you want to create the comma separated string. Try this
List<HashTable> hashTable = new List<HashTable>();
foreach (DataRow rows in ListaItensTransferencia.Rows)
{
hashTable.Add(new HashTable("Id Bem", Convert.ToString(rows["Id Bem"])));
}

c# find keywords in a list and create new list from the found items

i am learning c# and have the following problem, i can not find a solution.
the code i am trying is:
string theString = "aaa XXX,bbb XXX,ccc XXX,aaa XXX";
List<string> listFromTheString= new List<string>(theString.Split(','));
List<string> listOfFoundItems = new List<string>();
for (int i = 0; i < (listFromTheString.Count); i++)
{
if(listFromTheString[i].Contains("aaa"))
{
listOfFoundItems.Add(listFromTheString[i]);
}
}
I would like to iterate through the list and create new items in a new list if a special keyword is found. The list listOfFoundItems does not get filled with the founds.
can you please give me a hint what i am doing wrong?
You can accomplish this more succinctly with LINQ:
string theString = ("aaa XXX,bbb XXX,ccc XXX,aaa XXX");
List<string> listFromTheString = new List<string>(theString.Split(','));
List<string> listOfFoundItems = listFromTheString.Where(s => s.Contains("aaa")).ToList();
The code you provided does work, though.
Here's an alternate, one-line version:
List<string> listOfFoundItems = theString.Split(',').Where(s => s.Contains("aaa")).ToList();
theString.Split(',').Where(p=>p.Contains("aaa")).ToList()
I know you want to fix your algorithm, but once you do, consider grokking this expression:
listofFoundItems = (from s in theString.Split(',')
where s.Contains("aaa")
select s).ToList();
The code you provide works fine. Given that, I suspect you may be having some string comparison issues.
This code may work better for you:
const string given = "aaa XXX,bbb XXX,ccc XXX,aaa XXX";
var givenSplit = new List<string>(given.Split(','));
var listOfFoundItems = new List<string>();
foreach(var item in givenSplit.Where(g => g.IndexOf("aAa", StringComparison.InvariantCultureIgnoreCase) > -1))
{
listOfFoundItems.Add(item);
}
// two items are added
string theString = ("aaa XXX,bbb XXX,ccc XXX,aaa XXX");
List<string> listFromTheString = new List<string>(theString.Split(','));
List<string> listOfKeywords = new List<string> { "aaa" };
List<string> found = (from str in listFromTheString
where listOfKeywords.Any(keyword => str.Contains(keyword))
select str).ToList<string>();

line number while querying with linq

I am using a stream reader to read a text file and then using Linq for retrieving the information
String fileContent = prodFileStreamReader.ReadToEnd();
var mydata = from con in fileContent.Split('$').Select(x => x.Trim())
where !String.IsNullOrEmpty(con)
select new BaseSegment
{
dataID = con.Substring(0, con.IndexOf('#')),
dataElms = con.Split('#').ToArray(),
dataCon = con,
lineNumber =
};
I would also like to get the line number. I tried using Index but I was not able to. How to query to get the index and assign it to lineNumber?
Try using the select that projects index into each item, as given in this msdn article: http://msdn.microsoft.com/en-us/library/bb534869.aspx
In your case something like this (not tested):
var mydata = fileContent.Split('$')
.Select(x => x.Trim())
.Where(con => !String.IsNullOrEmpty(con))
.Select((con, index) => new
{
dataID = con.Substring(0, con.IndexOf('#')),
dataElms = con.Split('#').ToArray(),
dataCon = con,
lineNumber = index
});
For starters, I would not read the file in as a big string. Use methods that could process it in small chunks. Use File.ReadLines() for example to read through the file line by line. It will be easier to get line numbers this way and much more efficient than reading it all at once only to split it up again.
const string filePath = ...;
var myData =
from pair in File.ReadLines(filePath)
.Select((LineNumber, Line) => new { LineNumber, Line })
where ...
select new BaseSegment
{
...
Line = pair.Line,
LineNumber = pair.LineNumber,
};
p.s., You should stick to the usual C# naming conventions. Public properties of your classes should use PascalCasing, not camelCasing and should not be abbreviated.
The code you use to process the content looks awkward. It could probably be improved if I knew what the files looked like. I'll leave that out until you could show us how it is.
How about this?
var animalList = from a in animals
select new { Animal = a, Index = animals.IndexOf(a) };
or in your case...
Index = fileContent.IndexOf(con)
if this whole data is going in myData then you can use the index directly from the myData.
Try This:
String fileContent = prodFileStreamReader.ReadToEnd();
var mydata = from con in fileContent.Split('$').Select(x => x.Trim())
where !String.IsNullOrEmpty(con)
select new BaseSegment
{
dataID = con.Substring(0, con.IndexOf('#')),
dataElms = con.Split('#').ToArray(),
dataCon = con,
lineNumber = Array.IndexOf(fileContent.Split('$').Select(x => x.Trim(),con)
};
Array.IndexOf(yourArrey,the string you looking for); -> will return the index in the arrey.
you can try something like this
long index = 0;
var xElementsAndNodes = from xmlElement in elementsColl
select new
{
Index = index += 1,
....
}

Categories