How to add existing string array value with this code? - c#

Variable.cs
public string[] CcEmails { get; set; }
Mail.cs
EDTO.CcEmails = dr["rsh_ccmail"].ToString().Split(';');
here i got two strings eg. xxxx#gmail.com ; yyy#gmail.com
MailProcess.cs
dataRPT1=get data from sql
EDTO.CcEmails = new string[dataRPT1.Rows.Count];
for (int i = 0; i < dataRPT1.Rows.Count; i++)
{
EDTO.CcEmails[i] = dataRPT1.Rows[i]["email_addr"].ToString();
}
Here i got list of string eg.aaa#gmail.com ......
I am try to add with existing but it add only new values..Anyone could help me..

I tend to use union, although that will remove duplicate entries. But to keep all entries you can use Concat on the array.
var emailString = "me#test.com;you#test.com";
string[] emails = emailString.Split(';');
string[] emailsFromSQL = new string[3];
emailsFromSQL[0] = "everyone#test.com";
emailsFromSQL[1] = "everyone2#test.com";
emailsFromSQL[2] = "everyone2#test.com";
//No Duplicates
var combined = emails.Union(emailsFromSQL).ToArray();
//Duplicates
var allCombined = emails.Concat(emailsFromSQL).ToArray();
Thanks

I find the easiest way of doing this is to create a list, add items to the list, then use string.Join to create the new string.
var items = new List<string>();
for (int i = 0; i < dataRPT1.Rows.Count; i++)
{
items.Add(dataRPT1.Rows[i]["email_addr"].ToString());
}
EDTO.CcEmails = string.Join(";", items);
Update after changed question:
If the type of the CcEmails is an array, the last line could be:
EDTO.CcEmails = items.ToArray();

Related

Creating a List<String> in Android Xamarin

I'm building an android application where I need to create a simple list of String items, which i will then add a specific control for each item in the list.
This is the list I want to create:
List<String> projects = new List<String>(); // How?
The code I was trying:
String projects = new string[] { "hey","yo","app","xamarin","c","xaml" };
I need to count the items, something like this:
int amount = projects.Count(); // Can I do this?
Then adding the controls for each item in the list
// Add the tiles, one by one
for (int i = 0; i < amount; i++)
{
// Inflate the tile
var tile = LayoutInflater.Inflate (Resource.Layout.Tile, null);
// Set its attributes
tile.FindViewById<TextView> (Resource.Id.projectName).Text = currentProject;
// Add the tile
projectScrollView.AddView (tile);
}
"currentProject" string is retrieved from SharedPreferences, just haven't got that far yet
var projects = new List<String>() { "hey","yo","app","xamarin","c","xaml" };
if you are using the array to store what values you want in your list use the foreach
List<string>project = new List<string>();
string[] projects = { "hey","yo","app","xamarin","c","xaml" };
foreach(string str in projects)
{
project.Add(str);
}
for (int i = 0; i < projects.Length; i++)
{
// Inflate the tile
var tile = LayoutInflater.Inflate (Resource.Layout.Tile, null);
// Set its attributes
tile.FindViewById<TextView> (Resource.Id.projectName).Text = currentProject;
// Add the tile
projectScrollView.AddView (tile);
}
// you can get items from your list by using project.Count, your List<string> instead of projects.Length your array and take information from your list and output your tiles that way
To initialize a List<string> with collection initializer use the below syntax.
List<String> projects = new List<String>(){"hey","yo","app","xamarin","c","xaml"};
Count is not a method it is a property. You need property syntax.
int amount = projects.Count;
int amount = projects.Length;
that is how you can set the value of the int. It doesnt appear that you are populating your list with that code.

C# How do I parse a text file of data of unknown row size to a 2D array?

I can easily pass a data file to a 2D array if I know the size of the data file, but thats pretty pointless when you want to add and remove data.
How can I instantiate a 2D array of that Data rows length that is global and not out of scope to the rest of the program?
Here is the usual code, for an array of 4 rows and 6 columns, but I want to add/remove data to the data file making it of unknown length in rows.
string[,] allStudentData = new string[4, 6];
string[] allStudents = File.ReadAllLines("data.txt");
for (int i = 0; i < allStudents.Count(); i++)
{
for (int j = 0; j < 6; j++)
{
string[] DataIn = allStudents[i].Split(',');
allStudentData[i, j] = DataIn[j];
}
}
Thanks for your ideas :-)
Why not use something mutable, like a List ?
You can add columns using the .Add() command, , and you can collapse it into an array when you're done with it (.ToArray())
you can do as below
var result = File.ReadAllLines("data.txt").Select(x=>x.Split(',')).ToArray();
You can use a List that holds a custom object (it could be an array) instead of Array and then at the end convert the list to an array with the ToArray extension:
var list = new List<string[]>();
var data1 = new string[2] {"1", "2" };
var data2 = new string[3] {"1", "2", "3" };
list.Add(data1);
list.Add(data2);
list.ToArray(); // converts the list to string[][]
After you are done reading the file you could add easily more items to the list and then at the end write all modifications to the file. If you think, that in future you will need more than the two dimensional array, than it's worth it to create a custom object like:
public class Student
{
public string Name { get; set; }
public int Grade { get; set; }
}
and use this instead of the string[]:
var studentData = new List<Student>();
The maintenance later will be much more easier (adding address, classes, and so on). I admit, you will have a little more work to do when reading and writing, but if the project grows it will pay off.
You can still use LINQ to read the data on one line:
// creates a List<Student>
var studentData = File.ReadAllLines("data.txt")
.Select(row => row.Split(','))
.Select(elements =>
new Student
{
Name = elements[0],
Grade = int.Parse(elements[1])
}).ToList();
If the number of columns is always 6 and only the number of rows is unknown. Just change the first 2 rows of your code to:
string[] allStudents = File.ReadAllLines("data.txt");
string[,] allStudentData = new string[allStudents.Count(), 6];
If the number of columns is unknown you can do this to get a 2D result:
var not2DResult = File.ReadAllLines("data.txt").Select(x => x.Split(',')).ToArray();
var maxRow = not2DResult.Count()-1;
int maxColumn = Enumerable.Select(not2DResult, c => c.Count()).Max()-1;
var result2D = new string[maxRow, maxColumn];
for (int rowNumber = 0; rowNumber < maxRow; rowNumber++)
{
var row = not2DResult[rowNumber];
for (int columnNumber = 0; columnNumber < row.Count(); columnNumber++)
{
result2D[rowNumber, columnNumber] = row[columnNumber];
}
}
Try using a Lists to hold the file information.
var myList = new List<string>();
myList = File.ReadLines("data.txt");
var my2DList = new List<List<string>>();
foreach(string line in myList)
my2DList.Add(line.Split(','));
If you want to know the number of lines, just use:
int numberOfLines = my2DList.Count;
For the number of items in an individual line:
int lengthOfLine3 = my2DList[3].Length;

List sorting by multiple parameters

I have a .csv with the following headers and an example line from the file.
AgentID,Profile,Avatar,In_Time,Out_Time,In_Location,Out_Location,Target_Speed(m/s),Distance_Traveled(m),Congested_Duration(s),Total_Duration(s),LOS_A_Duration(s),LOS_B_Duration(s),LOS_C_Duration(s),LOS_D_Duration(s),LOS_E_Duration(s),LOS_F_Duration(s)
2177,DefaultProfile,DarkGreen_LowPoly,08:00:00,08:00:53,East12SubwayportalActor,EWConcourseportalActor,1.39653,60.2243,5.4,52.8,26.4,23,3.4,0,0,0
I need to sort this .csv by the 4th column (In_time) by increasing time ( 08:00:00, 08:00:01) and the 6th (In_Location) by alphabetical direction (e.g. East, North, etc).
So far my code looks like this:
List<string> list = new List<string>();
using (StreamReader reader = new StreamReader("JourneyTimes.csv"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
line.Split(',');
list.Add(line);
}
I read in the .csv and split it using a comma (there are no other commas so this is not a concern). I then add each line to a list. My issue is how do I sort the list on two parameters and by the headers of the .csv.
I have been looking all day at this, I am relatively new to programming, this is my first program so I apologize for my lack of knowledge.
You can use LINQ OrderBy/ThenBy:
e.g.
listOfObjects.OrderBy (c => c.LastName).ThenBy (c => c.FirstName)
But first off, you should map your CSV line to some object.
To map CSV line to object you can predefine some type or create it dynamically
from line in File.ReadLines(fileName).Skip(1) //header
let columns = line.Split(',') //really basic CSV parsing, consider removing empty entries and supporting quotes
select new
{
AgentID = columns[0],
Profile = int.Parse(columns[1]),
Avatar = float.Parse(columns[2])
//other properties
}
And be aware that like many other LINQ methods, these two use deferred execution
You are dealing with two distinct problems.
First, ordering two columns in C# can be achieved with OrderBy, ThenBy
public class SpreadsheetExample
{
public DateTime InTime { get; set; }
public string InLocation { get; set; }
public SpreadsheetExample(DateTime inTime, string inLocation)
{
InTime = inTime;
InLocation = inLocation;
}
public static List<SpreadsheetExample> LoadMockData()
{
int maxMock = 10;
Random random = new Random();
var result = new List<SpreadsheetExample>();
for (int mockCount = 0; mockCount < maxMock; mockCount++)
{
var genNumber = random.Next(1, maxMock);
var genDate = DateTime.Now.AddDays(genNumber);
result.Add(new SpreadsheetExample(genDate, "Location" + mockCount));
}
return result;
}
}
internal class Class1
{
private static void Main()
{
var mockData = SpreadsheetExample.LoadMockData();
var orderedResult = mockData.OrderBy(m => m.InTime).ThenBy(m => m.InLocation);//Order, ThenBy can be used to perform ordering of two columns
foreach (var item in orderedResult)
{
Console.WriteLine("{0} : {1}", item.InTime, item.InLocation);
}
}
}
Now you can tackle the second issue of moving data into a class from Excel. VSTO is what you are looking for. There are lots of examples online. Follow the example I posted above. Replace your custom class in place of SpreadSheetExample.
You may use a DataTable:
var lines = File.ReadAllLines("test.csv");
DataTable dt = new DataTable();
var columNames = lines[0].Split(new char[] { ',' });
for (int i = 0; i < columNames.Length; i++)
{
dt.Columns.Add(columNames[i]);
}
for (int i = 1; i < lines.Length; i++)
{
dt.Rows.Add(lines[i].Split(new char[] { ',' }));
}
var rows = dt.Rows.Cast<DataRow>();
var result = rows.OrderBy(i => i["In_time"])
.ThenBy(i => i["In_Location"]);
// sum
var sum = rows.Sum(i => Int32.Parse(i["AgentID"].ToString()));

Getting a variable from a list of objects

How would you get a variable from each object in a list?
I've got this so far:
void SortList()
{
int j = modules.Count;
string[] titles = new string[j];
for (int i = 0; i > modules.Count; i++)
{
titles[i] =
}
}
And I'm trying to get the variable "code" from each object in modules.
thanks.
Implying modules is a list or an array,
void SortList()
{
int j = modules.Count;
string[] titles = new string[j];
foreach (String title in modules)
{
titles[i] = title.code
}
}
As stated by Cuong Le, you could also use Linq to get a shorter version (Depending of which .Net version you are on).
titles = modules.Select(x => x.code).ToArray();
You can use LINQ with simple code with Select method:
titles = modules.Select(x => x.code).ToArray();

Dynamic DataGrid Headers

I've a problem where i need to get the total number of columns, which defines the total columns. Currently i have a function which dictates the header text on the DataGrid.columns.
public static string ColumnHeader1 = Properties.Settings.Default.ColumnHeader1;
public void dataGridHeaders()
{
dataGrid.Columns[0].Header = ColumnHeader1;
dataGrid.Columns[1].Header = ColumnHeader2;
dataGrid.Columns[2].Header = ColumnHeader3;
dataGrid.Columns[3].Header = ColumnHeader4;
dataGrid.Columns[4].Header = ColumnHeader5;
dataGrid.Columns[5].Header = ColumnHeader6;
dataGrid.Columns[6].Header = ColumnHeader7;
dataGrid.Columns[7].Header = ColumnHeader8;
}
the string vars being read in from an xml settings file. What i'm looking to do is depending on how many strings in the xml file depicts how many columns there will be at runtime. Or adding an int var say..
public static int totalNumberOfColumns = 8;
and then iterating through a loop adding the columns.
are any of these ways possible?
Get your column header from the XML file into a string list
List<string> columnHeaderList = new List<string>();
foreach (string header in XmlColumnList)
columnHeaderList.Add(header);
where XmlColumnList is some array that is holding the values. Now add the following method which will add all the avalible column headers, as rwequired.
private void DataGridHeaders(List<string> headerList)
{
for (int i = 0; i < headerList.Count; i++)
dataGrid.Columns[i].Header = headerList[i];
}
I hope this helps.
var xmlSample = #"<DataGridColumnsHeader>
<ColumnHeaderText>Name</ColumnHeaderText>
<ColumnHeaderText>Country</ColumnHeaderText>
<ColumnHeaderText>Phone</ColumnHeaderText>
</DataGridColumns>";
var counter = 0;
var elementCount = XDocument.Load(new System.IO.StringReader(xmlSample)).XPathSelectElements("//ColumnHeaderText").Count();
foreach (var element in XDocument.Load(new System.IO.StringReader(xmlSample)).XPathSelectElements("//ColumnHeaderText"))
{
dataGrid.Columns[counter].Header = element.Value;
counter++;
}
Hope this helps!

Categories

Resources