How to get multidimensional length - of one axis - c#

I have an array such as
string[,] SSISVariableNameValue = new string[,]
{
{"DestinationConfigDB","dest db"},
{"DestinationServer","dest server"},
{"SourceConfigDB","source db"},
{"SourceServer","source server"},
{"SSISConfigFilter","filter"}
};
The .length property is listed as 10. How can i get the 'x' axis of this array..aside from dividing by 2?

An array has a Rank property to tell you the number of dimensions and a GetLength(int d) function to give you the size in a specific dimension. d = 0 .. Rank-1
So you want SSISVariableNameValue.GetLength(0);

Related

Is there a way to use similar method to OpenCv's MinMaxLoc to get a list of n max values instead of only one max value?

MinMaxLoc returns min and max values of a given input array, however I would like to gent the n max values of that array?
Is the only way to do a loop, if so how to to do it using OpenCvSharp?
My image is something like:
Here's how I would do it in python (my c# is rusty and I couldn't find anything on google about how to find the n largest elements in OpenCvSharp).
data = [[1,2,3],[4,5,6],[7,8,9]]
# first, collapse the 2 dimensional input into 1 dimension
collapsed_data = []
for row in data:
collapsed_data.extend(row)
# now sort the collapsed input and get the 5 largest elements
sorted_data = sorted(collapsed, reverse=True)
k_largest = sorted_data[:k]
Note, there are more efficient ways to do this using min/max heaps but that's a lot of code to write and i'm not sure if you need the performance. If you do, those solutions are a google away.
Assuming you have a rectangular array you can get the n max values by:
var numValuesToGet = 2;
var inputArray = new int[,] {{1,2},{3,4},{5,6}};
var result = inputArray.Cast<int>().OrderByDescending(x=>x).Take(numValuesToGet);
Likewise, you could get the n min values by replacing OrderByDescending with OrderBy.

how to get length of string [] []

I have 2D array of string defined as
string[][] input_data;
I can count the number of rows by input_data.GetLength(0)
but if I use input_data.GetLength(1) to get number of column, I always get
System.IndexOutOfRangeException was unhandled
Message=Index was outside the bounds of the array.
Source=mscorlib
StackTrace:
at System.Array.GetLength(Int32 dimension)
...
I also noticed that at debugging, when I hover my mouse on my array (after all the data has been inserted) it only shows the first value (number of row) like this: input_data| {string[18][]}, if I continue expand the array then it shows all the 18 row data with the column data, like this:
How do I get the number of column? (in this case it is 139)
What you posted is a jagged array, not a multi-dimensional array. It's a 1-D array that contains other arrays. There is no second dimension so you can't use data.GetLength(1). Each row can have a different number of columns.
You can get the minimum or maximum number of columns for each row with data.Max(r=>r.Length) or data.Min(r=>r.Length), eg:
var s=new string[][]{
new[] {"a","b"},
new[] {"a"}
};
Console.WriteLine("{0} {1}",s.Max(r=>r.Length),s.Min(r=>r.Length));
will print
2 1
To specify a multi-dimensional array, you need to use the [,] syntax:
var s=new string[,]{
{"a","b"},
{"c","d"},
{"e","f"}
};
Console.WriteLine("{0} {1}",s.GetLength(0),s.GetLength(1));
This will return :
3 2
GetLength(1) would work if you had a multidimensional array:
string[,] input_data = new string[27,139];
var columns = input_data.GetLength(1);
What you have now is a jagged array not a 2D array, so there is no guarantee that all items ('rows') have the same number of elements ('columns').
However in case you can't use multidimensional array for some reason and you are sure that the input will be that way you can use the length of the first element input_data[0].Length
I think you are confusing an array of arrays and a multi dimentional array, run this code :
string[][] array_of_arrays = new string[5][];
Console.WriteLine(array_of_arrays.Length);
array_of_arrays[0] = new string[5];
array_of_arrays[1] = new string[6];
Console.WriteLine(array_of_arrays[0].Length);
Console.WriteLine(array_of_arrays[1].Length);
string[,] multi_d_array = new string[4,2];
Console.WriteLine(multi_d_array.GetLength(0));
Console.WriteLine(multi_d_array.GetLength(1));
This is a jagged array. You can get the first dimensions size as 'input_data.GetLength(0)' and second dimension size as 'input_data.GetLength(1)'. Try it
Example:
string[,] input_data = new string[5,12];
var column1 = input_data.GetLength(0);
var column2 = input_data.GetLength(1);

Syntax to create a double[,] in C#

This seems extremely simple, yet I can't seem to find applicable documentation anywhere. In C#, how do you create a 'double[,]'? Specifically, the data I'm trying to represent is something like this:
[0,0] = 0
[0,1] = 1
[1,0] = 1
[1,1] = 2
I have tried [[0,1],[1,2]] and the equivalent with {{}{}} and {[][]} and various other things, but cannot seem to figure out the syntax. It seems that a simple [0,1] alone is a 'double[,]' but I would like to find a way to represent the above data (more than just 2 numbers).
What am I missing? If anyone can point me to some simple documentation, that would be great.
See Array initializers:
For a multi-dimensional array, the array initializer must have as many levels of nesting as there are dimensions in the array. The outermost nesting level corresponds to the leftmost dimension and the innermost nesting level corresponds to the rightmost dimension. The length of each dimension of the array is determined by the number of elements at the corresponding nesting level in the array initializer. For each nested array initializer, the number of elements must be the same as the other array initializers at the same level.
In our case:
double[,] a = { { 0, 1 }, { 1, 2 } };
A multi-dimensional double array:
Double[,] newdouble = new Double[2,2];
or
Double[,] newdouble = { { 0, 0 }, { 1, 1 } };
In order to create a two dimensional array that you can assign to, you are going to need to first allocate the correct size. In this case, you have 2 rows and 2 columns, so that will be a [2,2].
double[,] twod = new double[2,2];
Next you simply assign to it like this
twod[0,0] = 0;
twod[0,1] = 1;
twod[1,0] = 1;
twod[1,1] = 2;
And then work with it however you wish.
There is three ways to initialized your array:
double[,] twoDemn = { { 0 , 1 }, { 1 , 2 } };
or:
double[,] twoDemn = new double[,] { { 0 , 1 }, { 1 , 2 } };
or:
double[,] twoDemn = new double[2,2];
twoDemn[0,0] = 0;
twoDemn[0,1] = 1;
twoDemn[1,0] = 1;
twoDemn[1,1] = 2;

shipping boxes sizes find largest side and smallest size

I am doing some shipping calculations. I need some help trying to figure this out.
Basically, I have a generic list of products with Length, Width, and Height properties.
I would like to EASILY look at the products and find the largest values of all three properties.
From here, I can do some math and figure out the box size based on the # of products.
My initial thought would be to make 3 arrays and find the max of each. Just wanted to see if there was a simpler or cooler way I didnt' know.
Sounds like an array of arrays. As you read each element (box) from your data source (SQL Server, XML, etc), create an 3-member array and insert the attributes in order of size. Then, add the three-member array to an array of arrays. You can then sort the array of arrays by the first, second or third member using LINQ or some other function.
Box1,2,2,3
Box2,5,10,1
Box3,8,4,7
Becomes:
{ {10,5,1}, {8,7,4}, {3,2,2} } // First
or
{ {8,7,4}, {10,5,1}, {3,2,2} } // Second
or
{ {8,7,4}, {3,2,2}, {10,5,1} } // Third
Then, you can sort the array by the first element, second element, etc.
You could easily build an array of arrays in a single statement using LINQ, but exactly how you would do so depends on the data source. Assuming you have an class named Box with three parameters, Length, Width and Height, and that you have created a strongly-typed collection containing instances of this class:
class BoxSorter {
public IEnumerable<Box> Boxes {
get;
private set;
}
class Box {
public double Height {
get;
set;
}
public double Width {
get;
set;
}
public double Length {
get;
set;
}
}
public void Initialize() {
this.Boxes = new List<Box>( new Box[] {
new Box() { Height = 2, Length = 2, Width = 3 },
new Box() { Height = 5, Length = 10, Width = 1 },
new Box() { Height = 8, Length = 4, Width = 7 }
} );
}
public void Sort() {
var l_arrayOfArrays =
this.Boxes.Select(
// Create an array of the Height, Length and Width, then sort the array elements (largest to smallest)
b => new double[] { b.Height, b.Length, b.Width }.OrderByDescending( v => v ).ToArray()
);
var l_dimension1 =
l_arrayOfArrays.OrderByDescending(
// Sort the array of arrays by the first (and largest) dimension
a => a[0]
);
var l_dimension2 =
l_arrayOfArrays.OrderByDescending(
// Sort the array of arrays by the second (and middle) dimension
a => a[1]
);
var l_dimension3 =
l_arrayOfArrays.OrderByDescending(
// Sort the array of arrays by the third (and smallest) dimension
a => a[2]
);
}
}
What you probably need to do is to have a set of box sizes and THEN try packing them optimally in one or more boxes of that size.
This is a simple packer for the 2D case, you can extend this to 3D.
Your algorithm will sorta look like
foreach box in boxes (ordered by decreasing volume)
while there are unpacked items
if box has space
pack item
else
box = another box of the same size
Now you can decide what to do with unused space in the last box - either pick them all out and try a smaller box, or try packing all items in all size boxes and then pick the combination that results in least number of boxes.
You are really having a problem finding the min, max, and middle of three numbers?
It does not make sense to take the smallest of each column as if you had just two
4 x 4 x 4
8 x 8 x 2
You would incorrectly conclude the smallest is 4 x 4 x 2 and the largest is 8 x 8 x 4.
double[] dimensions;
dimensions = new double[] {8,7,7};
Array.Sort(dimensions);
System.Diagnostics.Debug.WriteLine(dimensions[0]);
System.Diagnostics.Debug.WriteLine(dimensions[1]);
System.Diagnostics.Debug.WriteLine(dimensions[2]);
dimensions = new double[] { 7, 9, 8 };
Array.Sort(dimensions);
System.Diagnostics.Debug.WriteLine(dimensions[0]);
System.Diagnostics.Debug.WriteLine(dimensions[1]);
System.Diagnostics.Debug.WriteLine(dimensions[2]);
P.S. I agree with anathonline that it is way more complex than just simple math if you want an optimal box size and how to pack the items.

Difference between array.GetLength(0) and array.GetUpperBound(0)

What is the difference between these two methods and when would you use one instead of the other?
int[,] array = new int[4,3];
int length0 = array.GetLength(0);
int upperbound0 = array.GetUpperBound(0);
MSDN says that GetLength return the number of elements where as GetUpperBound determine the max index, but how could this be different since arrays are initialized with elements for each index?
Take a look at this (rarely used) method. From Docs:
public static Array CreateInstance(Type elementType, int[] lengths, int[] lowerBounds)
Creates a multidimensional Array of the specified Type and dimension lengths, with the specified lower bounds.
With it, you can create an array with indices from -5 ... +5. If you ever use this kind of array, then GetUpperBound() suddenly becomes a lot more useful than GetLength()-1. There also exists a GetLowerBound().
But the C# support for this kind of arrays is low, you cannot use []. You would only need those methods in combination with the Array.GetValue() and SetValue() methods.
Array.Length returns the length of the array (number of elements) you need
to subtract 1 from it to get the UpperBound.
Array.GetUpperBound(0) returns the upper bound of the array, you can use it
as is.
GetUpperBound returns the highest index in the array, the GetLength returns the number of elements of the array.
i.e. GetUpperBound = GetLength - 1
Generally, array.GetUpperBound(0) = array.Length - 1, but since we can create arrays that have a Nonzero lower bound, that is not always true.
I realise this is an old question but I think it's worth emphasising that GetUpperBound returns the upper boundary of the specified dimension. This is important for a multidimensional array as in that case the two functions are not equivalent.
// Given a simple two dimensional array
private static readonly int[,] USHolidays =
{
{ 1, 1 },
{ 7, 4 },
{ 12, 24 },
{ 12, 25 }
};
The Length property will output 8 as there are 8 elements in the array.
Console.WriteLine(USHolidays.Length);
However, the GetUpperBound() function will output 3 as the upper boundary of the first dimension is 3. In other words I can loop over array indexes 0, 1, 2 and 3.
Console.WriteLine(USHolidays.GetUpperBound(0));
for (var i = 0; i <= USHolidays.GetUpperBound(0); i++)
{
Console.WriteLine("{0}, {1}", USHolidays[i, 0], USHolidays[i, 1]);
}
if lower bound of your array is 0 then you can use either of them without any confusion but i would recommend array.length-1 as it is widely used. however, if the lower bound of your array is less than 0 then you should use array.GetUpperBound(0) because in this case array.length-1 != array.getUpperBound(0)

Categories