Retrieving values from multidimensional arrays - c#

I have an array something like this:
int[,] multiDimensionalArray2 = { { 1, 2 }, { 4, 5 } };
if I want to retrieve 1 and 2 and feed them into this:
int a;
int b;
How do I do it?
Is it something like this:
multiDimensionalArray2[0,0]
What if I wanted to put more numbers in the same form e.g. { { 2, 1 }, { 4, 1 } };, in the same form as above. Would it be something like this:
int[,] multiDimensionalArray2 = { { 1, 2 }, { 4, 5 } },{ { 2, 1 }, { 4, 1 } };
To retrieve the second set would I do this, multiDimensionalArray2[1,1]

You´re close, to retrieve the first numbers try this
var a = multiDimensionalArray2[0, 0]; // x == 1
var b = multiDimensionalArray2[0, 1]; // x == 2
Did you give it a try and it didn´t work? You´ll notice that SO users will encourage you to try-and-error first. Come back when you hit a wall :)

Double dimention arrays are stored like this (picture it in your mind) as per your example
Row0 Row1
1 2
4 5
2 1
4 1
Now follow what Dominik suggested.

If you have a multi dimensional array like the one you gave,
int[,] multiDimensionalArray2 = { { 1, 2 }, { 4, 5 }, { 2, 1 }, { 4, 1 } };
We want to get the index of the number 5. To do this we need two indexes, [a,b]
Index a is the index of the "group of numbers" that you want to get.
First look at which group it is in. The first group (index 0) contains 1 and 2, the second group (index 1) contains 4 and 5.
Therefore a = 1.
Index b is the index of the "position within the group" that you want to get.
In the group {4, 5}, the number 5 is the first item (index 0). Therfore b = 0.
This means that the number 5 can be found at multiDimensionalArray2[1,0]

Chao, I search documents in MSDN site for you, you should give it a try if you want.
Here is how I see on MSDN
List< > >
Dictionary<>
I guess it works for your problem too, it can dynamically grow longer or shorter. they say using generic classes might be better, I am not sure about whether it ought to be faster or not though.

Related

Reading a single element from HDF5 file

Could you please provide me with an example of reading a single element from HDF5 file using HDF5DotNet library. I know how to read the full array into the memory and select the necessary element by index. The problem that I don't want to read the full array and would like to use the H5S.selectElements method (http://hdf5.net/api/M_HDF5DotNet_H5S_selectElements_4_9e6f2387.aspx).
So far I've created the following:
H5.Open();
H5FileId fileId = H5F.open(this.filePath, H5F.OpenMode.ACC_RDONLY);
var dSet = H5D.open(fileId, "/Link");
var dSpace = H5D.getSpace(dSet);
var dDims = H5S.getSimpleExtentDims(dSpace);
var dType = H5D.getType(dSet);
H5S.selectElements(dSpace, H5S.SelectOperator.SET, InpPtr numElements,long [] coord);
I can not figure out how to define the numElements parameter and coord of the element (I have 3 dimensional array).
Using the HDF5 support doc
Assuming your DataSet is As Follows: (2D for simplicity explaining how the parameters work)
1 2 3
4 5 6
7 8 9
And you wanted to select the 6 and only the 6.
That means that you want one element located in the second row and the third column. (One Indexed).
That means that you will need a 1 by 2 array of points in the selection array. (Zero Indexed).
1 2
If you wanted to select the 7 also, then the selection array would look like this. (Zero Indexed).
1 2 2 0
The related calls would be:
H5S.selectElements(dSpace, H5S.SelectOperator.SET, 1, new long [] { 1, 2 });
H5S.selectElements(dSpace, H5S.SelectOperator.SET, 2, new long [] { 1, 2, 2, 0 });
Translating to a 3D dataspace, we just add an extra value to the selection array.
That is:
1 2 0
Will select the point (2,3,1)
If you wanted to select a second value, then the selection array would look like this. (Zero Indexed).
1 2 0 1 2 1
Will select the points (2,3,1), (2,3,2).
The related calls would be:
H5S.selectElements(dSpace, H5S.SelectOperator.SET, 1, new long [] { 1, 2, 0 });
H5S.selectElements(dSpace, H5S.SelectOperator.SET, 2, new long [] { 1, 2, 0, 1, 2, 1 });
Note: That I have never used HDF5, describing call based on documentation, so there may be errors.
Using HDFql in C#, reading one particular element of a three dimensional dataset can be done as follows (assume that the dataset is called my_dataset and the element to read is at position 2, 3 and 5 in the first, second and third dimension respectively):
HDFql.Execute("SELECT FROM my_dataset(2, 3, 5)");
From there, you can retrieve the element by doing the following (assume that my_dataset is of datatype integer):
HDFql.CursorFirst();
System.Console.WriteLine("Element is " + HDFql.CursorGetInt());
I've found another approach to solve the problem - using H5S.selectHyperslab method. Maybe it's not so elegant but it seems to work fine.
H5.Open();
H5FileId fileId = H5F.open(this.filePath, H5F.OpenMode.ACC_RDONLY);
var dSet = H5D.open(fileId, "/Link");
var dSpace = H5D.getSpace(dSet);
var dDims = H5S.getSimpleExtentDims(dSpace);
var dType = H5D.getType(dSet);
//E.g. to extract the value with coordinates [0,1,0]:
H5DataSpaceId memspaceid = H5S.create_simple(1, new long[] { 1, 1, 1 });
H5S.selectHyperslab(memspaceid, H5S.SelectOperator.SET, new long[] { 0, 1, 0 }, new long[] { 1, 1, 1 });
H5S.selectHyperslab(dSpace, H5S.SelectOperator.SET, new long[] { 0, 1, 0 }, new long[] { 1, 1, 1 });
//array to read data
double[] readDataBank = new double[1];
H5DataTypeId typeId = new H5DataTypeId(H5T.H5Type.NATIVE_DOUBLE);
H5D.read(dSet, dType, memspaceid, dSpace,new H5PropertyListId(new H5P.Template()), new H5Array<double>(readDataBank));

c# foreach loop not able to add literals in an array

Firstly I know that I can't use a foreach loop in C# to add values in let's say an array... But why? Why for example I can't do this
int[] numbers = { 1, 4, 3, 5, 7, 9 };
foreach (int item in numbers)
{
numbers[item] = 2;
}
Does it have something to do with the actual realisation of the foreach loop in the back-end? And how does the foreach loop exactly work? I know that it goes through the whole collection(array) but how exactly?
You are passing in the value of an item (your variable, item, will be the value of the array at each position in sequence, not the index) in the array as the index. The index used there is meant to be the position of the item you are attempting to access, not the value. So each iteration of the loop you are calling:
numbers[1]
numbers[4]
numbers[3]
numbers[5]
numbers[7]
numbers[9]
The array has 6 numbers, so when you get to numbers[7], you are asking for a value that is not there, hence the exception.
A better method of doing what you are trying to do would be:
for(int i = 0; i < numbers.Length; i++)
{
numbers[i] = 2;
}
On each iteration of this loop you would be accessing:
numbers[0]
numbers[1]
numbers[2]
numbers[3]
numbers[4]
numbers[5]
I'm looking at this:
numbers[item] = 2;
In this expression, you're using the item variable like an index, as if it had the values 1, 2, 3, 4, etc. That's not how the foreach iteration variable works for C#. The only language I know that does it this way is Javascript.
Remember that foreach and for are not the same thing. Just about every other language, including C#, gives you the actual array values in the item variable of a foreach loop: 1,4, 3, 5 etc. Now, these are integers, so you could try to use them as indexes. You can run the loop for a while like that... until you get to the value 7. At this point, your array only has six values. You're trying to do this:
numbers[7] = 2;
for an array where the largest valid index you can use is 5.
This is true even taking your modification of the array into account. Let's look at the array after each iteration through the loop:
{ 1, 4, 3, 5, 7, 9 } //initial state
{ 1, 2, 3, 5, 7, 9 } // after 1st iteration (index 0). Value at index 0 is 1, so item as index 1 is set to 2
{ 1, 2, 2, 5, 7, 9 } // after 2nd iteration (index 1). Value at index 1 is now 2, so item at index 2 is set to 2
{ 1, 2, 2, 5, 7, 9 } // after 3rd iteration (index 2). Value at index 2 is now 2, so item at index 2 is set to 2
{ 1, 2, 2, 5, 7, 2 } // after 4th iteration (index 3). Value at index 3 is 5, so item at index 5 is set to 2
// The 5th iteration (index 4). Value at index 4 is 7, which is beyond the end of the array
For the why of this... it sounds like you're used to a more dynamic language. Some these other languages, like php or Javascript, don't have real arrays at all in the pure computer science sense. Instead, they have collection types they'll call an array, but when you get down to it are really something different.
C# has real arrays, and real arrays have a fixed size. If what you really want is a collection, C# has collections, too. You can use List<T> objects, for example, to get an array-like collection you can append to easily.
For the other languages, the results vary depending on what you're talking about, but for the most permissive the result of your 5th iteration is something like this:
{ 1, 2, 2, 5, 7, 2, ,2 }
Note the missing value at index 6. That kind of things leads to mistakes that slip through your tests and don't show up until run-time. You also need to start wondering just how densely or sparsely the array will be filled, because the best strategy for handling these arrays can vary wildly depending on your answer... everything from just a big backing array with empty nodes that the programmer has to know about all the way to Hashtables and Dictionaries. And, by the way, C# again has these options available to you.
You need to step through your code in a debugger.
A for statement is more like a while statement, not like a foreach.
The line int[] numbers = { 1, 4, 3, 5, 7, 9 }; create this:
numbers[0] = 1;
numbers[1] = 4;
numbers[2] = 3;
numbers[3] = 5;
numbers[4] = 7;
numbers[5] = 9;
Your foreach statement does this:
numbers[1] = 2;
numbers[4] = 2;
numbers[3] = 2;
numbers[5] = 2;
numbers[7] = 2; <- this line overflows your array!
numbers[9] = 2; <- and so would this.
You have to learn the difference between an array index and an array value.
You need to create counter, in other case you trying to access item outside of array
int[] numbers = new int[]{ 1, 4, 3, 5, 7, 9 };
int i = 0;
foreach (int item in numbers)
{
numbers[i] = 2;
i++;
}
// Print the items of the array
foreach (int item in numbers)
{
Console.WriteLine(item);
}

Check times a value is next to the same value in an array

Lets say I have this array on C#:
int myList = {1,4,6,8,3,3,3,3,8,9,0}
I want to know if a value (lets say from 0-9) is next to itself in the list and how many times. In this case, the value 3 is next to itself and it has 4 repetitions. If I have a list {0,1,2,3,4,5,5,6,7} the value 5 is next to itself and has 2 repetitions.
Repetitions have a limit of 5. No value can be repeated more than 5 times. The far I went is making if statements, but I know there's a better way of doing it.
The standard of question is not that good but writing the answer
int lastValue = myList[0];
int times = 0;
foreach (int value in myList) {
if (lastValue == value) {
times++;
}
else if (times <= 1) {
lastValue = value;
times = 1;
}
else
break;
}
You only have to iterate on your list and keep a counter that will count only the consecutive duplicate integer.
If you want a neater solution, you might look at using an open source library called morelinq (by Jon Skeet and few others) on nuget. It has useful extension methods for LINQ.
One of them is called GroupAdjacent, which is applicable to your problem.
var testList = new[] { 1, 4, 6, 8, 3, 3, 3, 3, 8, 9, 0 };
var groups = testList.GroupAdjacent(t => t);
var groupsWithMoreThanOneMember = groups.Where(g => g.Count() > 1);

why does Enumerable.Except returns DISTINCT items?

Having just spent over an hour debugging a bug in our code which in the end turned out to be something about the Enumerable.Except method which we didn't know about:
var ilist = new[] { 1, 1, 1, 1 };
var ilist2 = Enumerable.Empty<int>();
ilist.Except(ilist2); // returns { 1 } as opposed to { 1, 1, 1, 1 }
or more generally:
var ilist3 = new[] { 1 };
var ilist4 = new[] { 1, 1, 2, 2, 3 };
ilist4.Except(ilist3); // returns { 2, 3 } as opposed to { 2, 2, 3 }
Looking at the MSDN page:
This method returns those elements in
first that do not appear in second. It
does not also return those elements in
second that do not appear in first.
I get it that in cases like this:
var ilist = new[] { 1, 1, 1, 1 };
var ilist2 = new[] { 1 };
ilist.Except(ilist2); // returns an empty array
you get the empty array because every element in the first array 'appears' in the second and therefore should be removed.
But why do we only get distinct instances of all other items that do not appear in the second array? What's the rationale behind this behaviour?
I certainly cannot say for sure why they decided to do it that way. However, I'll give it a shot.
MSDN describes Except as this:
Produces the set difference of two
sequences by using the default
equality comparer to compare values.
A Set is described as this:
A set is a collection of distinct
objects, considered as an object in
its own right

C# Calculate items in List<int> values vertically

I have a list of int values some thing like below (upper bound and lower bounds are dynamic)
1, 2, 3
4, 6, 0
5, 7, 1
I want to calculate the column values in vertical wise like
1 + 4 + 5 = 10
2 + 6 + 7 = 15
3 + 0 + 1 = 4
Expected Result = 10,15,4
Any help would be appreciated
Thanks
Deepu
Here's the input data using array literals, but the subsequent code works exactly the same on arrays or lists.
var grid = new []
{
new [] {1, 2, 3},
new [] {4, 6, 0},
new [] {5, 7, 1},
};
Now produce a sequence with one item for each column (take the number of elements in the shortest row), in which the value of the item is the sum of the row[column] value:
var totals = Enumerable.Range(0, grid.Min(row => row.Count()))
.Select(column => grid.Sum(row => row[column]));
Print that:
foreach (var total in totals)
Console.WriteLine(total);
If you use a 2D array you can just sum the first, second,... column of each row.
If you use a 1D array you can simply use a modulo:
int[] results = new results[colCount];
for(int i=0, i<list.Count; list++)
{
results[i%colCount] += list[i];
}
Do you have to use a "List"-object? Elseway, I would use a twodimensional array.
Otherwise, you simply could try, how to reach rows and columns separatly, so you can add the numbers within a simply for-loop. It depends on the methods of the List-object.
Quite inflexible based on the question, but how about:
int ans = 0;
for(int i = 0; i < list.length; i+=3)
{
ans+= list[i];
}
You could either run the same thing 3 times with a different initial iterator value, or put the whole thing in another loop with startValue as an interator that runs 3 times.
Having said this, you may want to a) look at a different way of storing your data if, indeed they are in a single list b) look at more flexible ways to to this or wrap in to a function which allows you to take in to account different column numbers etc...
Cheers,
Adam

Categories