I am trying to use Index and Range objects to slice a jagged array. But in the example below I cannot extract columns, only rows.
var A = new float[3][];
A[0] = new float[] { 1.1f, 1.2f, 1.3f };
A[1] = new float[] { 2.1f, 2.2f, 2.3f };
A[2] = new float[] { 3.1f, 3.2f, 3.3f };
// This works as intended to extract rows
var A_row1 = A[0][..]; // { 1.1, 1.2, 1.3 }
var A_row3 = A[^1][..]; // { 3.1, 3.2, 3.3 }
var A_row23 = A[1..^0][..]; // { { 2.1, 2.2, 2.3}, { 3.1, 3.2, 3.3 } }
// This does not work as intended to extract columns
var A_col1 = A[..][0]; // { 1.1, 1.2, 1.3 } ** WRONG
var A_col3 = A[..][^1]; // { 3.1, 3.2, 3.3 } ** WRONG
var A_col23 = A[..][1..^0]; // { { 2.1, 2.2, 2.3}, { 3.1, 3.2, 3.3 } } ** WRONG
var A_sub22 = A[0..2][0..2];
// { { 1.1, 1.2, 1.3 }, { 2.1, 2.2, 2.3 } } ** WRONG
// { { 1.1, 1.2 }, { 2.1, 2.2 } } <= WHAT I AM EXPECTING
Why is it that A[..][0] returns the exact same result as A[0][..]? And why doesn't the last statement contain 2 columns per row, but 3?
The bigger picture here is that I am building a Matrix object that stores the numeric data in a jagged array of double and I want to implement slicing using Index and Range. I thought I could have it support slicing with the following methods
public class Matrix
{
readonly double[][] Elements;
///<summary>Reference a single element</summary>
public ref double this[Index row, Index column]
=> ref Elements[row][column];
///<summary>Extract a sub-matrix</summary>
public double[][] this[Range rows, Range columns]
=> Elements[rows][columns];
///<summary>Extract a row sub-vector</summary>
public double[] this[Index row, Range columns]
=> Elements[row][columns];
///<summary>Extract a column sub-vector</summary>
public double[] this[Range rows, Index column]
=> Elements[rows][column];
}
But this failed spectacularly in my unit testing. It seems that even if C# supports the syntax, the results are unexpected.
Is there a way to implement the functionality I want to have using the existing framework for slicing that C# is trying to implement?
Sorry, I come from a Fortran background where slicing is natural.
Also, am I the only one that finds it very confusing that the last element in an array is indexed as [^1] but the range to the last element is [..^0]. It seems very inconsistent on the part of Microsoft to have ^0 mean different things for Index as it does for Range.
A[..]returns all rows.A[..][0]returns the first item in those rows.A[..]doesn't change the contents of those rows. To get what you wanted you'd have to change how the data is stored and transpose rows into columnsdf["Price"]would return the contents of thePriceraw in all three languagesfloat[,]). If you use that, you might be able to get the columns.am I the only one that finds it very confusing that the last element...yes and no - that syntax follows Python conventions, which is used by all data scientists. The last item is excluded. So[..^1]would exclude the last element. And yes, this is confusing for people that haven't work with Python and Pandas. Changing a common convention would be worse though