C# Listing/Checking Object Variables? - c#

With an ASP.NET MVC project I'm working on, I am required to check whether bit variables within a LINQ-To-SQL class are true. So far, After checking whether or not each variable is true or false, I then push the value of the field into a List and return it like so:
public List<String> GetVarList() {
List<String> list = new List<String>();
if (fields.SearchBar) {
list.Add("SearchBar");
}
if (fields.SomeField) {
list.Add("SomeField");
}
return list;
}
This, to me, doesn't seem to be the fastest or easiest way to do it.
I was wondering its possible to somehow be able check the value of the variable dynamically from an array of strings by looping through them with either a for or a foreach loop. For instance:
public List<String> GetVarList() {
String[] array = {"SearchBar", "SomeField"};
List<String> list = new List<String>();
foreach (String field in array) {
// Check whether or not the value is true dynamically through the array
}
return list;
}
Thanks for any suggestions!

Certainly, you can use reflection for something like this:
private bool ValueWasSet(string propertyName)
{
var property = fields.GetType().GetProperty(propertyName);
return (bool)property.GetValue(fields, null);
}
public List<string> GetVarList()
{
return new [] {"SearchBar", "SomeField"}
.Where(ValueWasSet)
.ToList();
}
It is a very straight-forward solution to what you want to do, assuming you have a lot of items to look through.
CAVEAT: This is NOT faster than your code. Your code is much faster than this... but if you want to do it more dynamically, you have to pay a slight perf price.

You can use reflection:
public List<String> GetVarList() {
String[] array = {"SearchBar", "SomeField"};
List<String> list = new List<String>();
var type=fields.GetType();
foreach (String field in array) {
var prop=type.GetProperty(field);
if ((bool)prop.GetValue(fields,null))
list.Add(field);
}
return list;
}
From your question is not clear if SearchBar, SomeFields etc. are fields or properties. If they are fields, change the code accordingly (use GetField() instead of GetProperty())

Related

Add elements to a list while iterating over it

I'm trying to add new elements to a list of lists while iterating over it
List<List<String>> sets = new List<List<string>>();
foreach (List<String> list in sets)
{
foreach (String c in X)
{
List<String> newSet = ir_a(list, c, productions);
if (newSet.Count > 0)
{
sets.Add(newSet);
}
}
}
The error I get after a few loops is this:
Collection was modified; enumeration operation may not execute
I know the error is caused by modifying the list, so my question is: What's the best or most fancy way to sort this thing out?
Thanks
You might get away with this in other languages but not C#. They do this to avoid funny runtime behaviour that isn't obvious. I prefer to set up a new list of things you are going to add, populate it, and then insert it after the loop.
public class IntDoubler
{
List<int> ints;
public void DoubleUp()
{
//list to store elements to be added
List<int> inserts = new List<int>();
//foreach int, add one twice as large
foreach (var insert in ints)
{
inserts.Add(insert*2);
}
//attach the new list to the end of the old one
ints.AddRange(inserts);
}
}
Imagine that if you had a foreach loop, and you added an element to it each time, then it would never end!
Hope this helps.

Variable string editing

I have a form on which you can select multiple items to create a code.
Eg. if I clicked on "name", it would add that to the string, then if I clicked "age" it would then add that to the string, but if I unchecked "name", it would remove it from the string.
I have no idea of how to go about this. Can someone help?
Take a List<string> and add/remove items to/from the list. Once you are done, you make a call to string.Join and construct a single string from array.
List<string> items = new List<string>(); // declare globally
private void add(string item)
{
items.Add(item);
}
private void remove(string item)
{
items.Remove(item);
}
private string convertArrayToString(string delimiter, List<string> elements)
{
delimiter = (delimiter == null) ? "" : delimiter;
return string.Join(delimiter, elements.ToArray());
}
Note:
Giving a priority to List<T> over string[] would be a good decision since, here collection would be resize. Have a look at this discussion which can help you on this.
Simply use a List.
List<string> myList = new List<string>();
myList.Add("Somestring");
Then you can use the following methods:
myList.Remove or myList.RemoveAll or myList.RemoveAt and so on.
Why not using List? it allows you to add/remove elements easily?
if you click on name, just add it to the list, when you uncheck the name, remove it from the list,
after that, you can convert your list into a string and use it.
//Add string
var myList = new List<string>();
//After clicking:
myList.add(clickedElement);
//After uncheck
myList.remove(uncheckedElement);
//At the end, just convert your list to string to use it
var myString = string.Join(" ", myList.ToArray());

Arrays/Array Lists

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.)

How can I read string value and store it in a array using data reader

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();

Stuck with List<>

I have this:
public class accounts
{
private string mName;
private string mEmail;
private string mAddress;
public accounts(string Name,
string Email,
string Address)
{
this.mName = Name;
this.mEmail = Email;
this.mAddress = Address;
}
}
then, somewhere else, I create this:
private static List<accounts> mlocalaccountList = new List<accounts>()
then I fill it like this:
mlocalaccountList.Add(new accounts("John Smith","johnsmith#mail.com","CA USA"));
Now, everything is OK, except, how can I access the list<> items??
You can access them in a foreach loop:
foreach (var item in mlocalaccountList) {
...
}
however, since all members are private you cannot access them at all. Consider making properties for the private members or making them public.
You can also access them by index:
mlocalaccountList[0]
is the first item in the list.
By indexer like an array
mlocalaccountList[0]
foreach (accounts a in mlocalaccountList) { /* do something */ }
will iterate through the list.
Try mlocalaccountList[0] or
foreach (accounts acct in mlocalaccountList)
{
// Do something with acct
}
I would recommend using a foreach statement or just access by using an index variable mlocalaccount[index]
You can iterate over them:
foreach (var item in mlocalaccountList)
{
// do stuff with item
}
You can use LINQ:
var usaItems = mlocalaccountList.Where(a => a.Address.Contains("USA"));
// assuming you implement a public property for Address
Here's a link to the List<T> MSDN page. The Members page lists all the methods and properties that you have available. You can find help on ForEach for example.
The MSDN library (http://msdn.microsoft.com/en-us/library/) is an invaluable source of information on the classes and their members.
Just combining the list of everyone's answers here so far:
Use an indexer into the list: mlocalaccountsList[i] will return the i'th element (0-based index, of course)
Iterate over the list using a loop. foreach(var account in mlocalaccountList) will easily provide you with each element in turn.
Use a LINQ query to filter out a specific element in the list. LINQ has two different styles of writing queries:
var result = mlocalaccountList.Where(a => a.Name == "John Smith"))
// or
var result = from a in mlocalaccountList
where a.Name == "John Smith"
select a;
Use a foreach statement:
foreach (accounts acc in mlocalaccountList)
{
... do something with acc
}
Though I don't program in C#, I believe it is: mlocalaccountList[index] where index is an int.

Categories