I'd like to populate an arraylist by specifying a list of values just like I would an integer array, but am unsure of how to do so without repeated calls to the "add" method.
For example, I want to assign { 1, 2, 3, "string1", "string2" } to an arraylist. I know for other arrays you can make the assignment like:
int[] IntArray = {1,2,3};
Is there a similar way to do this for an arraylist? I tried the addrange method but the curly brace method doesn't implement the ICollection interface.
Depending on the version of C# you are using, you have different options.
C# 3.0 has collection initializers, detail at Scott Gu's Blog
Here is an example of your problem.
ArrayList list = new ArrayList {1,2,3};
And if you are initializing a collection object, most have constructors that take similar components to AddRange, although again as you mentioned this may not be an option.
Array list has ctor which accepts ICollection, which is implemented by the Array class.
object[] myArray = new object[] {1,2,3,"string1","string2"};
ArrayList myArrayList = new ArrayList(myArray);
(kind of answering my own question but...)
The closest thing I've found to what I want is to make use of the ArrayList.Adapter method:
object[] values = { 1, 2, 3, "string1", "string2" };
ArrayList AL = new ArrayList();
AL = ArrayList.Adapter(values);
//or during intialization
ArrayList AL2 = ArrayList.Adapter(values);
This is sufficient for what I need, but I was hoping it could be done in one line without creating the temporary array as someone else had suggested.
Your comments imply you chose ArrayList because it was the first component you found.
Assuming you are simply looking for a list of integers, this is probably the best way of doing that.
List<int> list = new List<int>{1,2,3};
And if you are using C# 2.0 (Which has generics, but not collection initializers).
List<int> list = new List<int>(new int[] {1, 2, 3});
Although the int[] format may not be correct in older versions, you may have to specify the number of items in the array.
I assume you're not using C# 3.0, which has collection initializers. If you're not bothered about the overhead of creating a temp array, you could do it like this in 1.1/2.0:
ArrayList list = new ArrayList(new object[] { 1, 2, 3, "string1", "string2"});
Related
Is there a linq function in c# which enables you to collect IEnumerables from a specific range of indexes?
An example would be
var objectArray = new string[] { "Bill", "Bob", "Joe", "Phil", "Tom", "Paul" };
var indexArray = new int[] { 1, 3, 5 };
var list = objectArray.Where(SOME_FUNCTION_TO_GET_INDEXES ??).ToList();
//output would be list:
//Bob
//Phil
//Paul
Just use Select with your indexArray and return the item from objectArray via indexing.
var list = indexArray.Select(i => objectArray[i]);
Note that this works very efficiently for any collection that allows indexing (for example, Array and List<T>). In the more general case of having an IEnumerable or ICollection, you wouldn't be able to index directly. In which case you'd need to see Jon's answer. Depending on the sizes of the lists involved, and how many items you need to look up, it might be worth converting your IEnumerable to an Array or List (using ToArray for example) first.
If the original datasource is already accessible by index, such as for a list or an array, you can just use indexArray.Select as Matt showed.
If you've got an IEnumerable<T> instead, you can use the Where overload which provides the index as well as the value. So:
var list = objectArray.Where((value, index) => indexArray.Contains(index))
.ToList();
I have a List<int> myInts and want to multiply all with 10. I want to use linq (not foreach loop).I tryed this but nothing happend:
List<int> myInts = new List<int>() { 1, 2, 3 };
myInts .ForEach(act => act=act*10);
Of what do I have to take care in the .ForEach(...) part? And yes, I want to use ForEach if it is somehow possible.
Probably its simple, but I cant see it, I apoligize. Thank you all!
This creates a new instance of List.
myInts = myInts.Select(p=>p*10).ToList();
Another and simpler solution:
list = list.ConvertAll(i => i * 10);
"Nothing happens" because reassigning to the local variable (act) has no effect in the caller (ForEach) - C# is Call By Value (except for ref/out parameters).
To modify the list in place, simply use a standard for-each over the indices (which I find readable and upfront of the side-effect intent):
var myInts = new List<int>() { 1, 2, 3 };
for (var i = 0; i < myInts.Count; i++) {
myInts[i] = myInts[i] * 10;
}
To perform the operation and create a new list/sequence (which can be re-assigned to the same variable), see IEnumerable.Select which is a map transformation.
From MSDN documentation:
Modifying the underlying collection in the body of the Action<T> delegate
is not supported and causes undefined behavior.
So, you need to project your exisistin List into a new one, or you need to use a for loop if you must modify the List "in place"
Regards
What is happening is that you are getting a value copy of the int to your the lambda, which so you won't be able to change the 'external' int.
How about projecting a new list?
List<int> myInts = new List<int>() { 1, 2, 3 };
myInts = myInts.Select(act => act*10).ToList();
To use a .Select or .ConvertAll are good solutions.
But my intention was to let "ForEach" return an alterd list.
I found out, over msdn documentation, that this isn´t possible because ForEach is a void type and has no returntype.
This kind of action works if I would have objects in my List instead of ints. Then I would be able to use the "void" Method to change the properties of my objects.
Do you mean like this ?
List<int> _tempList = new List<int>();
myInts.ToList().ForEach(x => _tempList.Add(x * 10));
try this:
Enumerable.Range(0, myInts.Count).ToList().ForEach(i => myInts[i] = myInts[i] * 10);
Ive just seen a piece of code that uses a generic list class to instantiate itself in the following manner:
var foo = new List<string>(){"hello", "goodbye"};
The curly braces after the contructor are especially confusing. It reminds me somewhat of
var bar = new string[]{"hi","bye"};
but in the past i've wouldve always used:
var foo = new List<string>(new []{"hello", "goodbye"});
Has anybody got a link explaining the syntax in the first line of code? I wouldnt even know where to begin with googling it.
As others have pointed out, that is a collection initializer. Some other features you might not be aware of that were added to C# 3:
A collection initializer constructor may omit the parentheses if the argument list is empty. So new List<int> { 10, 20, 30 } is fine.
An array initialized with an array initializer may in some cases omit the type. For example, var myInts = new[] { 10, 20, 30}; infers that myInts is int[].
Objects may be initialized using a similar object initializer syntax. var c = new Customer() { Name = "Fred" }; is the same as var temp = new Customer(); temp.Name = "Fred"; var c = temp;
The point of these features is to (1) make more things that used to require statements into things that require only expressions; LINQ likes things to be expressions, and (2) to enable richer type inference, particularly for anonymous types.
Finally: there has been some confusion in some of the answers and comments regarding what is required for a collection initializer. To be used with a collection initializer the type must (1) implement IEnumerable (so that we know it is a collection) and (2) have an Add method (so that we can add stuff to it.)
See
http://blogs.msdn.com/b/madst/archive/2006/10/10/what-is-a-collection_3f00_.aspx
for additional thoughts on the design of the feature.
here you go. The keyword is "Array Initializers".
http://msdn.microsoft.com/en-us/library/aa664573(v=vs.71).aspx
or rather "Collection Initializers"
http://msdn.microsoft.com/en-us/library/bb384062.aspx
This is a collection initializer: http://msdn.microsoft.com/en-us/library/bb384062.aspx
The type so initialized must implement IEnumerable and have an Add method. The items in the curly-brace list are passed to the add method; different items in the list could be passed to different Add methods. If there's an Add overload with more than one argument, you put the multiple arguments in a comma-separated list enclosed in curly braces.
For example:
class MyWeirdCollection : IEnumerable
{
public void Add(int i) { /*...*/ }
public void Add(string s) { /*...*/ }
public void Add(int i, string s) { /*...*/ }
//IEnumerable implementation omitted for brevity
}
This class could be initialized thus:
var weird = new MyWeirdCollection { 1, "Something", {5, "Something else"} };
This compiles to something like this:
var temp = new MyWeirdCollection();
temp.Add(1);
temp.Add("Something");
temp.Add(5, "Something else");
var weird = temp;
In his blog post (link posted by Eric Lippert in the comments), Mads Torgersen expresses this concisely:
The list you provide is not a “list of elements to add”, but a “list of sets of arguments to Add methods”. ...[W]e do separate overload resolution against Add methods for each entry in the list.
In the third line of code you provided you are making a new string array, and then passing that string array to the list. The list will then add each of those items to the list. This involves the extra overhead of allocating the array, populating it, and then discarding it.
There is a mechanism for a class to define how to use Collection Initializers to populate itself. (See the other answers) I have never found the need to utilize this for my own classes, but existing data structures such as List, Dictionary, often define them, and they are useful to use.
This is a collection initializer. You can use it on collections with an Add method.
The pair of parentheses before the curly braces is optional.
This is very convenient, because you can use it on collections other than lists, for example on dictionaries:
var x = new Dictionary<int,string> {{1, "hello"}, {2, "world"}};
This lets you avoid a lengthier initialization sequence:
var x = new Dictionary<int,string>();
x.Add(1, "hello");
x.Add(2, "world");
Hi guys I have 2 different List 1 that holds items that I see as a requirements and the other one is user provided. I need to check all the List passed on to me against my List and get all items that the user failed to include. The checking is based on item class type. Is there any way I can do this without looping on my list and comparing one by one?
EDIT:
By the way I'm still using .net 2.0 which no Lambda expression yet.
EDIT 2:
Thanks for the answer. I guess I'm stuck on looping with it but found some pretty nice way to make it far better than the old one does.
Not sure I'm in full understanding of what you're asking, but I think you have a list of types and then a list of objects and you want to see what types are missing in the list of objects. Is that correct? If so, you may be searching for something like this
List<Type> types = new List<Type>() { typeof(int), typeof(double), typeof(float) };
List<object> objects = new List<object>() { 1, 2, 3, 2d, 4d };
var missingTypes = types.Except(objects.Select(obj => obj.GetType()));
Which, in this case, would result in a sequence that simply contains the type for float. By using LINQ, you are looping but it is abstracted away.
Edit: In .NET 2.0, you can do something like the following to get your missing types. You're still looping, but it's not too bad. You might be able to write this better, and you could certainly write it better in 3.5+ (even without LINQ), but it should get you started.
static IEnumerable<Type> GetMissingTypes(IEnumerable<Type> types, List<object> objects)
{
List<Type> existingTypes = objects.ConvertAll(delegate(object obj) { return obj.GetType(); });
foreach (Type type in types)
{
if (!existingTypes.Contains(type))
yield return type;
}
}
// ...
List<Type> types = new List<Type>() { typeof(int), typeof(double), typeof(float) };
List<object> objects = new List<object>() { 1, 2, 3, 2d, 4d };
IEnumerable<Type> missingTypes = GetMissingTypes(types, objects);
You can use IEnumerable.Except like this:
requirements.Except(userProvided,
delegate (T req, T user)
{
req.GetType().Equals(user.GetType());
});
Stuck looping regardless. Syntatical sugar or not, either its a loop in code or a loop by the compiler.
jtdubs is on the right track, only using a method outside of 2.0. Cycle through either collection and use a delegate as a Predicate to Find instances in the other. Not the prettiest but 2.0 was pretty clunky when dealing with collection manipulation. It is what it is.
Rather than looping, you could do a sort and then compare. Without any code samples from you we can all just keep guessing though. Can you use your "item class type" as a string? If so a sort and compare will be much faster and you won't be looping either.
How many items in a list are we talking about?
In preparing you for Linq, consider the following
string[] reqs = { "A", "C", "E", "Z" };
string[] list = { "A", "E", "Z", "C" };
string[] unmet = Array.FindAll(reqs,
delegate(string item)
{
return !Array.Exists(list, item.Equals);
});
bool all_done = unmet.Length == 0;
where reqs is the requirements and list is the user supplied items. The Array class has many static methods for handing arrays pre-linq. Use them as they are a life saver in .NET 2.0
The unmet array will tell you what is missing.
Can you cast a List<int> to List<string> somehow?
I know I could loop through and .ToString() the thing, but a cast would be awesome.
I'm in C# 2.0 (so no LINQ).
.NET 2.0 has the ConvertAll method where you can pass in a converter function:
List<int> l1 = new List<int>(new int[] { 1, 2, 3 } );
List<string> l2 = l1.ConvertAll<string>(delegate(int i) { return i.ToString(); });
Updated for 2010
List<int> l1 = new List<int>(new int[] { 1,2,3 } );
List<string> l2 = l1.ConvertAll<string>(x => x.ToString());
Is C# 2.0 able to do List<T>.Convert? If so, I think your best guess would be to use that with a delegate:
List<int> list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
list.Convert(delegate (int i) { return i.ToString(); });
Something along those lines.
Glenn's answer is probably the correct code ;-)
You can use:
List<int> items = new List<int>(new int[] { 1,2,3 } );
List<string> s = (from i in items select i.ToString()).ToList();
You wouldn't be able to directly cast it as no explicit or implicit cast exists from int to string, it would have to be a method involving .ToString() such as:-
foreach (int i in intList) stringList.Add(i.ToString());
Edit - or as others have pointed out rather brilliantly, use intList.ConvertAll(delegate(int i) { return i.ToString(); });, however clearly you still have to use .ToString() and it's a conversion rather than a cast.
result = listOfInt.Select(i => i.ToString(CultureInfo.InvariantCulture)).ToList()
replace the parameters result and listOfInt to your parameters
Converting from int List to string List can be done in two adittional ways besides the usual ToString(). Choose the one that pleases you more.
var stringlist = intlist.Select(x=>""+x).ToList();
Or also:
var stringlist = intlist.Select(x=>$"{x}").ToList();
And finally the traditional:
var stringlist = intlist.Select(x=>x.ToString()).ToList();
You have to build a new list. The underlying bit representations of List<int> and List<string> are completely incompatible -- on a 64-bit platform, for instance, the individual members aren't even the same size.
It is theoretically possible to treat a List<string> as a List<object> -- this gets you into the exciting worlds of covariance and contravariance, and is not currently supported by C# or VB.NET.