So I have an array coming in with hotels information and one piece I need out of it is the location of each hotel so then I can send that into a different method. So I have my first foreach setup, but now I am wondering how to collect all of the data on the locations into a string array so I can send that out after all of the hotels are read. Can someone help, thanks.
// API call to get the info
ContentAPI.BasicHotelMedia[] rawData = DataHelper.NewContentAPI().GetBasicHotelMedia(ProductCode, ProductYear, SiteBrand);
//setting up the datatable
DataTable dtHotels = InitHotelTable();
//set my variables
foreach (ContentAPI.BasicHotelMedia item in rawData)
{
DataRow dr = dtHotels.NewRow();
dr["HotelCode"] = item.BasicHotelCode;
dr["HotelDescription"] = item.BasicDescription;
dr["WiFi"] = item.HasWifi;
// This is the variable that i need set in the string array so i can send into another method
dr["SellingLocation"] = item.BasicSellingLocation;
// Add other raw data
// Get other info about the hotel
GetHotelMedia(item.BasicHotelCode, ProductYear, item.HasWifi, ref dr);
dtHotels.Rows.Add(dr.ItemArray);
}
I'd suggest using a List instead of initializing a string[]. They're just easier to work with.
Llike this:
var locations = new List<string>();
foreach (ContentAPI.BasicHotelMedia item in rawData)
{
...
locations.Add(item.BasicSellingLocation);
}
OtherMethod(locations.ToArray());
Related
I have a method I am using for a test that takes the data in a table row, turns it into a string then uses the Split() function to add each different string to an object in my class. I then take that and try and add it to a list of the same class. Each time it runs through the foreach loop it is just updating each object to the new data that is supposed to be added so that the data is the same in each index whereas it is supposed to be different. How can I fix this?
Here is the method:
public List<IMUItemModel> tableData()
{
_webDriver.Wait.UntilPageLoadIsComplete(60);
List<IMUItemModel> IMUDataList = new List<IMUItemModel>();
IMUItemModel IMUData = new IMUItemModel();
foreach (var row in IMUDataTableRows)
{
string column = row.Text;
var split = column.Split(' ');
IMUData.MedVendID = split[0];
IMUData.DeviceSerialNumber = split[1];
IMUData.ItemID = split[2];
IMUData.Station = split[3];
IMUData.Console = split[4];
IMUDataList.Add(IMUData);
Console.WriteLine(IMUData.MedVendID);
}
return IMUDataList;
}
You are creating a single instance of IMUData for entire list and so, the same reference is being assigned the values in each iteration. At the end of the iteration, all the items will have the data of last item because you just kept on updating the same reference.
To fix this,
move the below line inside the foreach loop
IMUItemModel IMUData = new IMUItemModel();
This will ensure you have a new reference each time you add an item to the list.
I'm trying to transfer my datatable contents to another array. I am only going to get specific fields from the datatable, but I do not know how to save the specific columns content to another array.
What I did:
dr = SuperViewBLL.GetSomeStuff();
string[] new_array;
if (dr.Rows.Count > 0)
{
for (int i = 0; i < dr.Rows.Count;i++ )
{
new_array[i] = dr.Rows[i]['StuffLocationId'];
// I do know this is wrong
}
}
How can I get the column StuffLocationId to the array new_array?
That line is almost right, except that you need double quotes rather than single and you also need to cast/convert the value to type String to put it into a String array:
new_array[i] = (string) dr.Rows[i]["StuffLocationId"];
or, if the data is nullable:
new_array[i] = dr.Rows[i]["StuffLocationId"] as string;
The issue is that the array doesn't exist because you haven't created it. In order to create an array you have to know the size. If you haven't specified a size, either implicitly or explicitly, then you haven't created an array. This:
string[] new_array;
should be this:
string[] new_array = new string[dr.Rows.Count - 1];
You can also throw a bit of LINQ at the problem and succinctify the code a bit:
var new_array = dr.AsEnumerable()
.Select(row => row["StuffLocationId"] as string)
.ToArray();
That's also an example of specifying the size of the array implicitly.
This way is much more clear:
dt = SuperViewBLL.GetSomeStuff();
List<string> list = new List<string>();
foreach(DataRow row in dt.Rows)
{
list.Add((!row.IsNull("StuffLocationId") ? row["StuffLocationId"] as string : string.Empty));
}
Updated with the help of #jmcilhinney
I am fairly new to C#
I am trying to retrieve some information from an external data source and store it in array, once it is in an array I wish to sort it by time.
I know how to do this for just one column in a row, however the information I require has multiple columns.
For example:
foreach (Appointment Appoint in fapts)
{
// Store Appoint.Subject, Appoint.Start, Appoint.Organiser.Name.ToString(), Appoint.Location in an array
}
// Sort my array by Appoint.Start
foreach ( item in myNewArray )
{
//print out Appoint.Subject - Appoint.Start, Appoint.Organiser.Name.ToString() and Appoint.location
}
Many thanks for your help.
EDIT:
I have multiple data sources which pull in this:
foreach (Appointment Appoint in fapts)
{
// Store Appoint.Subject, Appoint.Start, Appoint.Organiser.Name.ToString(), Appoint.Location in an array
}
Hence the need to sort the items in a new array, I know this isn't very efficent but there is no way of getting the information I need in any other way.
You can sort a list using the LINQ sorting operators OrderBy and ThenBy, as shown below.
using System.Linq;
and then...
var appointments = new List<Appointment>();
var sortedAppointments = list.OrderBy(l => l.Subject).ThenBy(l => l.Name).ToList();
This will create a new list of appointments, sorted by subject and then by name.
It's unclear what your final aim is but:
Use a generic List instead of an array:
See this SO question for more information as to why using a List is prefered.
List<Appointment> appointments = new List<Appointment>();
foreach (Appointment Appoint in fapts)
{
appointments.Add(Appoint);
}
foreach (var item in appointments)
{
Console.WriteLine(item.Subject);
Console.WriteLine(item.Foo);
// Here you could override ToString() on Appointment to print eveything in one Console.WriteLine
}
If the aim of your code is to order by time, try the following:
var sortedAppointments = fapts.OrderBy(a => a.Start); // assuming Start is a DateTime property of `Appointment`.
Consider a Dictionary Object instead of an array if the data is conceptually one row multiple columns.
foreach(KeyValuePair<string, string> entry in MyDic)
{
// do something with entry.Value or entry.Key
}
You already have a list of objects in fpts, sort that list itself:
fpts.OrderBy(x => x.Subject).ThenBy(x => x.Location).ToList();
LINQ is your friend here.
fapts appears to already be a collection so you could just operate on it.
var myNewArray = fapts.OrderBy(Appoint => Appoint.Start).ToArray()
I've used the ToArray() call to force immediate evaluation and means that myNewArray is already sorted so that if you use it more than once you don't have to re-evaluate the sort.
Alternatively if you are only using this once you can just as easily miss the ToArray() portion out and then execution of the sort will be deferred until you try and enumerate through myNewArray.
This solution puts the source objects into the array, but if you are just wanting to store the specific fields you mention then you will need to use a select. You have two choices for the array item type, you can either use an anonymous class which provides difficulties if you are returning this array from a function or define a class.
For anonymous:
var myNewArray = fapts.OrderBy(Appoint => Appoint.Start)
.Select(Appoint => new {
Start = Appoint.Start,
Organiser = Appoint.Organiser.Name.ToString(),
Location = Appoint.Location
}).ToArray();
For named class assuming class is MyClass:
var myNewArray = fapts.OrderBy(Appoint => Appoint.Start)
.Select(Appoint => new MyClass {
Start = Appoint.Start,
Organiser = Appoint.Organiser.Name.ToString(),
Location = Appoint.Location
}).ToArray();
You have a wide range of options. The 2 most common are:
1) Create a class, then define an array or list of that class, and populate that
2) Create a structure that matches the data format and create an array or list of that
Of course, you could put the data into an XML format or dataset, but that's probably more work than you need.
public List<foo> appointments = new List<foo>();
public struct foo
{
public string subject ;
public DateTime start ;
public string name ;
public string location ;
}
public void foo1()
{
// parse the file
while (!File.eof())
{
// Read the next line...
var myRecord = new foo() ;
myRecord.subject = data.subject ;
myRecord.start = data.Start ;
myRecord.name = data.Name ;
//...
appointments.Add(myRecord);
}
}
Enjoy
(Since I can't comment and reply to the comment - it wasn't clear if he had a class, etc. or was just showing us what he wanted to do. I assumed it was just for demonstration purposes since there wasn't any info as to how the data was being read. If he could already put it into a class, than the first answer applied anyway. I just tossed the last 2 in there because they were options for getting the data first.)
I am trying to add rows in the datarow one by one..For example first row is of list and second row is of list,then the third row is of list and fourth of list and so on..Here is my code ..
// Declaring a list of datahandling type data which contains
// groupid,stringid,stringtext etc.
List<Data> data = new List<Data>();
List<Data> diff = new List<Data>();
// Function which separates the relevant data from the string
// and stores it in the list.
control.Stringhandler(readcontents.Contents, ref data);
control.Stringhandler(readcontents.Translated_contents, ref diff);
foreach (var array in data)
{
datarows.Rows.Add(array.GroupID, array.StringID, array.StringText);
// datarows.Rows.Add(array.GroupID, array.StringID, array.StringText);
save = array.Lines + 1;
}
My question is that the foreach() adds data in the datarow,row by row ..I want to add diff row next to data row..
For example the datarow should be added in this way
datarow.row[0]=data;
datarow.row[1]=diff;
datarow.row[2]=data;
datarow.row[3]=diff;
That is what i am trying to do..
If both list are of <Data> type, you can concat first two list and then add rows. Like this
var lstCombined = data.Concat(diff)
foreach (var array in lstCombined )
{
datarows.Rows.Add(array.GroupID, array.StringID, array.StringText);
// datarows.Rows.Add(array.GroupID, array.StringID, array.StringText);
save = array.Lines + 1;
}
I am reading some list of values in the result but I am not sure where I am going wrong, I wont know the array size so I cant assign any value to it
string[] result = null;
while (reader.Read())
{
result = Convert.ToString[](reader["RoleID"]);
}
reader.Close();
I am getting: Syntax error; value expected.
After I get the result value, how can I compare the values inside the result with a string? For example, I want to check whether the string check="Can send message"; is present in the result array or not. How can I do that?
Your code is syntactically wrong, hence the error. But when you have to build a collection of items but you do not know the size in advance, you want to use a List<T> as opposed to an array. The list will allow you to keep adding items.
var results = new List<string>();
while (reader.Read())
{
results.Add(reader["RoleID"].ToString());
}
// results now holds all of the RoleID values in the reader
You can access the elements of the list via index, just like an array, and can query the list using Linq (also just like an array) if needed.
string check = "something";
if (results.Any(item => item.Equals(check)))
{
// results contains the value in check
}
// or use all items that equal check
foreach (var item in results.Where(obj => obj.Equals(check))
{
// do something with each item that equals check
}
I preffer using ArrayList
var result= new ArrayList();
while (reader.Read())
{
result.Add(Convert.ToString[](reader["RoleID"]));
}reader.Close();
You should use a list as follows:
var results = new List<string>();
while( reader.Read() ){
results.Add(reader["RoleID"].ToString());
}
Then you would iterate through all the strings in the collection and check them using a foreach statement:
foreach(var result in results) {
if(result == "check") {
// do something
}
}
The list in Anthony Pegram's example can easily be converted to an array if needed.
string[] result = results.ToArray();