tags:

views:

176

answers:

8

I m reading data from a source as array. a[n]

I need to add one more element to the array.

Once i get the array, i create a new array with capacity n+1 and copy all the elements to the new array and put the new element as the last element of the array.

I can do this.

Is there a better way to do this? especially with Linq?

+2  A: 

You could just use the array to initialize a list.

var stuff = new List<object>( a );
stuff.Add( moreStuff );
Ed Swangren
You should use a strongly-typed list.
SLaks
Replace `object` with `SomeType`
SLaks
The OP says nothing about what type he is working with, and I would assume he knows how to use a generic list. It's really beside the point.
Ed Swangren
If the OP is asking a question as elementary as is there some way to make an array resize, you shouldn't make any assumptions as to his knowledge of Generic collections, or his knowledge of the performance issues of casting/boxing/unboxing objects in generic collections. FFS, declaring List<object> defeats the whole point in the generic collection! You might as well use an Arraylist at this point.
highphilosopher
If the OP does not understand the purpose of generics my advice would be to stop this project entirely and start reading beginner's tutorials.
Ed Swangren
A: 

Use a List<T> instead, and call myList.Add(item)

Edit: if you meant you're getting data as an array (not reading the data into one), use the constructor for List to copy from the array.

Cogwheel - Matthew Orlando
+3  A: 

If you want to put to arrays together using LINQ, you can use Concat:

var combined = array1.Concat(new[] { element }).ToArray();

However, you are now creating a number of different arrays for your collection. A better choice would be to just use a List. It will be backed by a single array and expanded automatically for you.

Eric Hauser
+6  A: 

What you have described is really the only way to do it. Arrays cannot be resized in .NET, so we have to allocate a new array and copy the old into it. For example, this is how Array.Resize works. LINQ is not really a help here, and if it was, it would just be projecting the existing array into a new one anyway - which is exactly what we've just described.

If you find you need to resize the array often, you should consider using an ArrayList or, if possible, a strongly-typed List<T>.

Edit: If you are simply getting an Array from some method you cannot control, but within your code you could use an IEnumerable<T> instead, you can use LINQ to lazy-enumerate and spare the extra array allocation:

var mySequence = originalArray.Concat(new[]{myobj});

//snip

foreach(var item in mySequence)
{
    //do stuff
}

It's only when calling ToArray() that we incur the extra overhead. Otherwise we're simply doing a single enumeration over the original array and then sneaking the extra item(s) in at the end.

Rex M
unfortunately, the data source returns array, i cant help it.
@user what is stopping your from changing the datasource to a List once you receive it? Why keep it as an inflexible array?
Kirk Broadhurst
because i have to store it back as an array. so changing that to a list and then back to an array is an overkill isnt it?
+1  A: 

You can use Array.Resize for this: http://msdn.microsoft.com/en-us/library/bb348051.aspx

It basically does what you've done manually but is a bit neater.

If you are adding more than one element to the array on a regular basis I'd recommend moving to a list though as it's going to be more efficient for insertions.

Lummo
+1  A: 

You can use the ToArray and ToList Linq commands.

Here's a generic method that would return a new array that would be a copy of the original with the new item.

public static T[] AddItem<T>( T[] array, T item )
{
    List<T> list = array.ToList();
    list.Add( item );
    return list.ToArray();
}

Here's a generic extension method to add an item into an array. (The array would be a new one in memory so might have side effects).

public static void AddItem<T>( this T[] array, T item )
{
    List<T> list = array.ToList();
    list.Add( item );
    array = list.ToArray(); /* Untested, this may not compile! */
}
Jerod Houghtelling
This is slightly worse than simply copying the old array directly into the new one.
Rex M
I agree it's not the most efficient way to probably handle this. I like your use of the Concat method. I overlooked that one. I have up voted your answer.
Jerod Houghtelling
Have you actually tested that extension method? Because if it works, it means the `this` argument gets passed by reference, which would surprise me.
Isaac Cambron
@Isaac, unfortunately I didn't test that routine, it was an afterthought.
Jerod Houghtelling
I updated the code example to let somebody know that it might not work. I decided to leave it because I think an extension method for this may still be a good solution.
Jerod Houghtelling
I think it'll compile; it just won't have any effect.
Isaac Cambron
+2  A: 

C# yield (no extra storage needed)

Using C# yield allows you to return your array and more without ever allocating extra storage. After yielding each element of the original array you can slip in any extra elements easily like so:

IEnumerable<int> GetEverything() {

    // first return the entire original array
    foreach(int num in arrNumbers)
        yield return num;

    // then slip in extra element at the end
    yield return 5;   // yield even more elements if you want...
}

and then you can use it like so:

foreach (int n in GetEverything())
    Console.WriteLine(n);

There's no real need to pull out LINQ in this situation because the yield statement is simple and EXACTLY suited to your need.

John K
very nice solution
Space Cracker
A: 

you can use something like this, if you have to arrays from the same type {ArrayVar1,ArrayVar2}

var arrayList = ArrayVar1.ToList();
arrayList.AddRange(ArrayVar2); // or for single element use arrayList.Add(Var2);
ArrayVar1=arrayList.ToArray();
Waleed A.K.