With a 1D array, I can use the sum method to get the sum of all the values.
int[] array = {6,3,1};
Console.WriteLine(array.Sum());
With a multidimensional array (3D in my case), this can't be done. Obviously I could go all foreach on it, but this seems verbose and I suspect it will perform badly.
Is there a way to flatten the array? Or a nice way just to get the sum that I've not seen?
Sum does exactly foreach. There is no magic behind them. If you are so performance hungry use for instead of foreach. You can do this in parallel also, this operation can be easily parallelized.
this'll do the trick.
var i = array.SelectMany(j => j).Sum()
you could parallelize this in .net 4 like this
var i = array.AsParallel().SelectMany(k => k).Sum();
Why should a foreach perform badly? You have to read every value at least once to calculate the sum. There is no way around this (assuming "random" values, of course). So maybe there is a more beautyful way, but not a more performant one (speaking in terms of Big O).
If you have a jagged array and would like clean code you could use
int[][] array = { new []{ 6, 3, 1 }, new []{ 6, 3, 1 } };
Console.WriteLine(array.Sum(i => i.Sum()));
Related
I want to create a 2D jagged array (as previous so answers claims is faster on dot net than multidimensional one).
I want to do something like
Int [][] myarr = new int [2][3];
But C# doesn't seem to support this so I did use a for loop for the 2nd dimension instantiation.
Yet if I want to fastly reset I cant use memset equivalent as each new in the loop initiate the array in a possible different and not continouse place.
Is there a faster way to init and reset a fixed width jagged array ?
You can use LINQ and Enumerable.Range method, but internally there is still a loop performed:
int[][] myarr = Enumerable.Range(0, 2).Select(x => new int[3]).ToArray();
there is an array in c#
string[] arr = new string[] {"1","A","D","3","5","AF","34","TU","E","OP","4"};
so how can i get elements from middle of this array like below
string[] fromArr = new string[5];
fromArr = {"D","3","5","AF","34"};
Do u know any method or any way to do that?
The simplest way is to use LINQ2Objects
var fromArr = arr.Skip(2).Take(5).ToArray();
The most performant way would be to use Array.Copy, but that code would be much more cumbersome to write and you need to figure that out yourself, including handling all edge cases when the arrays are not long enough etc.
But if you will use the result just a few times you don't need to copy it back to an array, you can just use the lazy evaluation feature of LINQ2SQL
IEnumerable<string> fromArr = arr.Skip(2).Take(5);
then you can use fromArr in a loop or whatever without even copying the data in the first place.
When I think about it you may have the option to use ArraySegment<string> too instead of copying to new arrays.
But for the readability and simplicity, stick with the LINQ version unless you have a real reason to use another alternative.
LINQ has some good approaches to this. In your case
arr.Skip(2).Take(5).ToArray()
should produce what you need.
A reference is here: http://msdn.microsoft.com/en-us/library/bb386988.aspx
Use LINQ for this
arr.Skip(2).Take(5).ToArray()
You can use Array.copy to take a slice of an array, for your example:
string[] arr = new string[] {"1","A","D","3","5","AF","34","TU","E","OP","4"};
string[] fromArr = new string[5];
Array.Copy(arr, 2, fromArr, 0, 5);
This question is probably pretty stupid, but I'm new to C# and I'm not sure if there are any shortcuts to do this. I have a dynamic array for which the range will always be 1-n, with n being variable. Is there anyway to declare an array and have it hold incremental values without looping?
Think along the lines of my array holding values 1-50. I'd like to declare an array as such (logically): double[] myArray = new double[] {1-50} or, more generically for my purposes double[] myArray = new double[] {1-n}. I don't know what made me think of this, I just thought I'd ask.
I am going to bind this array (or list) to a combo box in WPF. I guess setting a combo-box the same way would also work if there's a shortcut for that.
Sorry for the dumb question. =)
int n = 50;
var doubleArray = Enumerable.Range(1, n).Select(x => (double)x).ToArray();
That will generate a sequence of integers from 1 to n (in this case 50) and then cast each one to a double and create an array from those results.
You could use a List<T> which represents a dynamic array to which you could add elements.
System.Linq.Enumerable.Range can generate än enumeration of int. Cast the enumeration if you really want double.
System.Linq.Enumerable.Range(1,20).ToArray()
http://msdn.microsoft.com/en-us/library/system.linq.enumerable.range.aspx
very basic question, but is there any ToArray-like function for c# linked lists that would return an array of only part of the elements in the linkedlist.
e.g.: let's say my list has 50 items and I need an array of only the first 20. I really want to avoid for loops.
Thanks,
PM
Use Linq?
myLinkedList.Take(20).ToArray()
or
myLinkedList.Skip(5).Take(20).ToArray()
You say you "really want to avoid for loops" - why?
If you're using .NET 3.5 (or have LINQBridge), it's really easy:
var array = list.Take(20).ToArray();
... but obviously that will have to loop internally.
Note that this will create a smaller array if the original linked list has fewer than 20 elements. It's unclear whether or not that's what you want.
Something is going to have to loop internally, sooner or later - it's not like there's going to be a dedicated CPU instruction for "navigate this linked list and copy a fixed number of pointers into a new array". So the question is really whether you do it or a library method.
If you can't use LINQ, it's pretty easy to write the equivalent code yourself:
int size = Math.Min(list.Count, 20);
MyType[] array = new MyType[size];
var node = list.First;
for (int i = 0; i < size; i++)
{
array[i] = node.Value;
node = node.Next;
}
That will actually be slightly more efficient than the LINQ approach, too, because it creates the array to be exactly the right size to start with. Yes, it uses a loop - but as I say, something's got to.
If you're using the LinkedList collection class (from System.Collections.Generic), you can use LINQ to get it:
var myArray = list.Take(20).ToArray();
I'm using jagged arrays and have a bit of a problem (or at least I think I do). The size of these arrays are determined by how many rows are returned in a database, so it is very variable. The only solution I have is to set the dimensions of the array to be very huge, but this seems ... just not the best way to do things.
int[][] hulkSmash = new int[10][];
hulkSmash[0] = new int[2] {1,2};
How can I work with jagged arrays without setting the dimensions, or is this just a fact of life with C# programming??
You've got 2 choices:
You can read the size of the information returned from the database, and allocate your array space at that time, once you know what you're getting.
Otherwise, what you're looking for is a data structure that has variable dimensions. Take a look at List for example: MSDN: List< T >
The other examples using List<T> and collections are the best way to proceed. I sometimes find the
List<List<int>> hulkSmash = new List<List<int>>();
syntax a tad unwieldy. Luckily, there are some options to manage this.
The first option I sometimes use is to make an alias:
using List<List<int>> = HulkSmashCollection;
This prevents you from having to do nested <<<Types>>> all the time. Everywhere you'd type List<List<int>> you can instead type HulkSmashCollection (or something shorter still) instead.
The second option is to wrap the List of Lists within a class called, say, MyHulkSmashes. Here, you only provide the functions/properties you need, like Count or Find() etc.
Both these concepts are used to reduce the amount of code on screen, and reduce perceived complexity.
List<List<int>> hulkSmash = new List<List<int>>();
hulkSmash.Add(new List<int>() { 1, 2 });
or
List<int[]> hulkSmash = new List<int[]>();
hulkSmash.Add(new int[] { 1, 2 });
A collection of ints (such as List) will give you the flexibility that you want and not waste space as would allocating an array that is much larger than you will ever need.