I have a set of servers for which I need the names, but I only want those that are currently available so I need a dynamically sized array. What data structure can I use to store these.
You probably want to use the the generic List<T> class, as in List<string>.
Let's say you have your server names in a comma-separated values string. Then you can use the Split and ToList() extension method (on IEnumerable) to convert it to a dynamically-sized list.
string input = "server1,server2,server3";
List<string> serverNames = input.Split(',').ToList();
Or if you are checking them one at a time using some other method.
List<string> serverNames = new List<string>();
foreach (var server in GetAvailableServers())
{
if (server.IsAvailable)
{
serverNames.Add( server );
}
}
A rough equivalent to C++'s Vector<t> in C# is a List<t>. Works as a dynamic array, allowing you to List.Add() and access it via index.
E.G.
List<string> names = new List<string>();
names.Add("John");
names.Add("Mike");
foreach (string name in names)
{
evaluate(name);
}
List<string> servers = new List<string>();
servers.Add("http://stackoverflow.com");
See msdn.
You're looking for the List<T> class.
Related
I am trying to do some group comparison in my web application and want to see if the current user is in a certain list of groups that I have stored in a SQL table. I currently am getting my groups in an array using this method...
public ArrayList GetGroups()
{
ArrayList groups = new ArrayList();
foreach (System.Security.Principal.IdentityReference group in
System.Web.HttpContext.Current.Request.LogonUserIdentity.Groups)
{
groups.Add(group.Translate(typeof
(System.Security.Principal.NTAccount)).ToString());
}
return groups;
}
From here I can check if the user is in a certain group by doing this
ArrayList al = new ArrayList();
al = GetGroups();
foreach (string s in al)
{
if (s == "some_group")
{
//do this;
}
}
I can get it working for individual or even a few groups but I have a SQL table with about 20 groups in it and I just wanted to use some sort of comparison between the array and my SQL table. I tried using a dataset and comparing them but I was not able to get that working. Any advice is appreciated I am just learning how to work in C#. Thank you.
Few things I noticed from your code:
There is no reason to use ArrayList. Instead use a List<T> where in your case, T would be string. This provides type safety and better performance.
You create a new instance of the ArrayList class and then you assign the result of GetGroups to that variable (al). You initialized an instance of the ArrayList for no purpose, you already created the instance in the GetGroups method.
I'm not quite sure what comparison you are wanting to do between the user groups and the SQL groups. Feel free to add more details, but you can do a very basic contains check like so:
List<string> userGroups = GetUserGroups();
List<string> sqlGroups = GetSqlGroups();
foreach (var sqlGroup in sqlGroups)
{
// case-sensitive check
if (userGroups.Contains(sqlGroup))
{
// the user has one of the SQL groups
}
// case-insensitive check
if (userGroups.Contains(sqlGroup, StringComparer.OrdinalIgnoreCase))
{
// the user has one of the SQL groups
}
}
You can get more advanced using LINQ or even if you need to consider cAsE sEnsiTiviTY, but you'll need to provide more details for that.
List<string> userGroups = new List<string>();
List<string> sqlGroups = new List<string>();
var containedGroups = sqlGroups.Where(item=>userGroups.Contains(item));
Generic List is better than ArrayList if you can make sure your data type.
I got a List<string> named Test:
List<string> Test = new List<string>();
I want to add a string to it using Test.Add();, but first I want to check if it already exists in the list.
I thought of something like this:
if (Test.Find("Teststring") != true)
{
Test.Add("Teststring");
}
However, this returns an error.
I assume that you if you don't want to add the item if it is already added
Try This:
if (!Test.Contains("Teststring"))
{
Test.Add("Teststring");
}
Any receives a Predicate. It determines if any element in a collection matches a certain condition. You could do this imperatively, using a loop construct. But the Any extension method provides another way.
See this:
bool b1 = Test.Any(item => item == "Teststring");
Also you can use :
if (!Test.Contains("Teststring"))
{
...
}
If you don't want to add an item twice it is a good indicator that you might use a HashSet<T> instead which is more efficient but doesn't allow duplicates(like a Dictionary with only keys).
HashSet<string> Test = new HashSet<string>();
bool newString = Test.Add("Teststring");
If you need to use the list use List.Contains to check if the string is already in the list.
What is the difference between HashSet and List in C#?
But your code suggests that you only want to add duplicates. I assume that this is not intended.
In my opinion you are using the wrong datastructure here. You should use Hashset to avoid duplicates.
The lookup time for Hashset is O(1) whereas for list it is O(n)
The HashSet class provides high-performance set operations. A set is a collection that contains no duplicate elements, and whose elements are in no particular order.
This is how your code should look like.
HashSet<string> Test = new HashSet<string>();
Test.Add("Teststring");
Use Test.Contains("TestString");
Sorry, I think I was not clear earlier. I am trying to do as O.R.mapper says below- create a list of arbitrary variables and then get their values later in foreach loop.
Moreover, all variables are of string type so I think can come in one list. Thanks.
Is there a way to store variables in a list or array then then loop through them later.
For example: I have three variables in a class c named x,y and Z.
can I do something like:
public List Max_One = new List {c.x,c.y,c.z}
and then later in the code
foreach (string var in Max_One)
{
if ((var < 0) | (var > 1 ))
{
// some code here
}
}
Is there a particular reason why you want to store the list of variables beforehand? If it is sufficient to reuse such a list whenever you need it, I would opt for creating a property that returns an IEnumerable<string>:
public IEnumerable<string> Max_One {
get {
yield return c.x;
yield return c.y;
yield return c.z;
}
}
The values returned in this enumerable would be retrieved only when the property getter is invoked. Hence, the resulting enumerable would always contain the current values of c.x, c.y and c.z.
You can then iterate over these values with a foreach loop as alluded to by yourself in your question.
This might not be practical if you need to gradually assemble the list of variables; in that case, you might have to work with reflection. If this is really required, please let me know; I can provide an example for that, but it will become more verbose and complex.
Yes, e.g. if they are all strings:
public List<string> Max_One = new List<string> {c.x,c.y,c.z};
This uses the collection initializer syntax.
It doesn't make sense to compare a string to an int, though. This is a valid example:
foreach (string var in Max_One)
{
if (string.IsNullOrEmpty(var))
{
// some code here
}
}
If your properties are numbers (int, for example) you can do this:
List<int> Max_One = new List<int> { c.x, c.y, c.Z };
and use your foreach like this
foreach(int myNum in Max_One) { ... } //you can't name an iterator 'var', it's a reserved word
Replace int in list declaration with the correct numeric type (double, decimal, etc.)
You could try using:
List<object> list = new List<object>
{
c.x,
c.y,
c.z
};
I will answer your question in reverse way
To start with , you cannot name your variable with "var" since it is reserved name. So what you can do for the foreach is
foreach (var x in Max_One)
{
if ((x< 0) || (x> 1 ))
{
// some code here
}
}
if you have .Net 3.0 and later framework, you can use "var" to define x as a member of Max_One list without worrying about the actual type of x. if you have older than the version 3.0 then you need to specify the datatype of x, and in this case your code is valid (still risky though)
The last point (which is the your first point)
public List Max_One = new List {c.x,c.y,c.z}
There are main thing you need to know , that is in order to store in a list , the members must be from the same datatype, so unless a , b , and c are from the same datatype you cannot store them in the same list EXCEPT if you defined the list to store elements of datatype "object".
If you used the "Object" method, you need to cast the elements into the original type such as:
var x = (int) Max_One[0];
You can read more about lists and other alternatives from this website
http://www.dotnetperls.com/collections
P.s. if this is a homework, then you should read more and learn more from video tutorials and books ;)
I have to write a query in a web application using LINQ but I need to change that query into an array list. How can I change the query below to do this?
var resultsQuery =
from result in o["SearchResponse"]["Web"]["Results"].Children()
select new
{
Url = result.Value<string>("Url").ToString(),
Title = result.Value<string>("Title").ToString(),
Content = result.Value<string>("Description").ToString()
};
If you really need to create an ArrayList, you can write new ArrayList(resultsQuery.ToArray()).
However, you should use a List<T> instead, by writing resultsQuery.ToList().
Note that, in both cases, the list will contain objects of anonymous type.
There is a .ToArray() method that'll convert IEnumerable to an Array.
ArrayList doesn't have a constructor or Add(Range) method that takes an IEnumerable. So that leaves two choices:
Use an intermediate collection that does implement ICollection: as both Array and List<T> implement ICollection can be used via the ToArray() or ToList() extension methods from LINQ.
Create an instance of ArrayList and then add each element of the result:
var query = /* LINQ Expression */
var res = new ArrayList();
foreach (var item in query) {
res.Add(item);
}
The former method is simple to do but does mean creating the intermediate data structure (which of the two options has a higher overhead is an interesting question and partly depends on the query so there is no general answer). The latter is more code and does involve growing the ArrayList incrementally (so more memory for the GC, as would be the case for an intermediate Array or List<T>).
If you just need this in one place you can just do the code inline, if you need to do it in multiple places create your own extension method over IEnumerable<T>:
public static class MyExtensions {
public static ArrayList ToArrayList<T>(this IEnumerable<T> input) {
var col = input as ICollection;
if (col != null) {
return new ArrayList(col);
}
var res = new ArrayList();
foreach (var item in input) {
res.Add(item);
}
return res;
}
}
i have a list contains set of strings, i want to fetch the data present in the list based on index, with out using iterator.. is there any functions like get() or getat() some sort of method using which we can fetch?
myList[index] is the way to go
List<string> myList = new List<string>();
myList.Add("string 1");
myList.Add("String 2");
Console.WriteLine(myList[0]); // string 1
Console.WriteLine(myList[1]); // String 2
List<string> myList = new List<string();
//add some elements to the list
//then get the third element
string thirdElement = myList[2];
You can just do:
item = list[i];
Use the overloaded index operator.
List<String> list; // ... initialize, populate list
String element = list[1]; // get the element at index 1
If your collection implements IList<T>, just use indexer. Otherwise, if your collection only allows forward-only access (that is, only implements IEnumerable<T>) you can use ElementAt() method, but it still uses iterator under the hood.
I don't know what kind of list you're talking about exactly, but most collections in .net have a CopyTo function, and you can access individual items with the [] operator.
List<string> list = new List<string>();
list.Add("lots of strings");
//If you want to print all the strings you can do:
foreach(string str in list)
Console.WriteLine(str);
//If you want to modify each string in the list, make each lower case for example,
// you can do. this is working by using the index of the elements in the list:
for(int i = 0; i < list.Count; i++)
list[i] = list[i].ToLower();
If you use the generic type List (or another implementation of IList) you can use the index operator to directly access items at certain positions: item = myList[3]
If you use a type that only implements IEnumerable you should use the ElementAt() function.
What's your reason to avoid the use of iterators?