none
C#中二维数据如何通过索引器获取行对象 RRS feed

  • 问题

  • 打算写一个矩阵类,希望通过Matrix.Rows[vRowIndex]来获取和设置某个数据行的值。代码改如何写?

    举例:

    有一个矩阵a

    1   2   3

    4   5   6

    7   8   9

    希望通过a.Rows[0]获取到{1   2   3}这个数组,并且可以通过a.Rows[0] = {3,2,1}把矩阵改为

    3   2   1

    4   5   6

    7   8   9

    2017年12月1日 8:50

答案

  • Hi,

    感谢你的反馈。 

    我们分析datatable 的代码,它的rows代码是通过下面的方法实现的,你可以参考一下。

    [Browsable(false), ResDescriptionAttribute(Res.DataTableRowsDescr)]
            public DataRowCollection Rows {
                get {
                    return rowCollection;
                }
            }
    https://referencesource.microsoft.com/#System.Data/System/Data/DataTable.cs,8aab738ad2b51b53

    据我分析,估计你的matrix类,要有collection 这个特性,你可以参考上面DataRowCollection代码,继承相关的基类。

    Best Regards,

    Hart


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 白极熊 2017年12月5日 17:37
    2017年12月5日 9:21
    版主

全部回复

  • Hi,

    欢迎在MSDN论坛发帖。

    根据MSDN的规则,对于代码逻辑的问题,我们不会直接提供代码服务,如果你在开发过程中遇到什么问题,请把相关代码抛出来,以方便其他社区成员帮助解决问题。

    就我个人观点,你可以尝试使用3维数组,然后在转换的时候,你可以遍历一维数组,最后返回来。

    三维数组,你可以尝试下面的代码。

    string[,] test= new string[3, 3] {{"a","b","c"},
                                       {"d","e","f"}, 
                                       {"g","h","i"} };

    然后遍历其中的一维数组。

     for (int j = 0; j < matrix[i].Length; j++)
    

    Best Regards,

    Hart


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年12月4日 6:14
    版主
  • 首先,非常感谢您的回答。

    但是,可能我没表达清楚我的意思。

    我现在做了一个矩阵类叫dyMatrix,内部是以一个二维数组存储矩阵的各元素的,如下:

    public class dyMatrix
    {
    public int Row;
    public int Col;
    public float[,] Data;

    #region 索引器

    public float this[int vRowIndex, int vColIndex]
    {
    get
    {
    return this.Data[vRowIndex, vColIndex];
    }
    set
    {
    this.Data[vRowIndex, vColIndex] = value;
    }
    }

    public dyMatrixRow this[int vRowIndex]
    {
    get
    {
    return this.GetRow(vRowIndex);
    }
    set
    {
    this.SetRow(vRowIndex, (dyMatrixRow)value);
    }
    }

    }

    通过索引器this[vRowIndex, vColIndex]可以访问单个矩阵元素,例如:this[3,5]表示第3行第5列的矩阵元素。

    通过索引器this[vRowIndex]可以访问矩阵行,例如:this[3]表示返回第3矩阵行。

    但是我现在希望通过this.Rows[3]来访问第3矩阵行,就不知道语法上该如何写。

    我记得以前的DataTable有类似的访问方法,所以我觉得应该是有对应的语法的。

    我现在就是请问C#这部分的语法该怎么写?

    PS:因为矩阵非常经常涉及到行操作和列操作,我的最终目的是实现下面目标:

    对于矩阵

    1   2   3

    4   5   6

    7   8   9

    执行下列代码:

    this.Rows[1] += this.Rows[2] ;

    结果变为

    1   2   3

    11 13 15  //第二行= 第二行+第三行

    7   8   9

    再执行

    this.Cols[1] += this.Cols[2] ;

    结果为

    1   5   3

    11 28 15

    7   17  9

    //第二列 = 第二列 + 第三列

    相关SetRow()、GetRow()、SetCol()、GetCol()代码已完成,运算符+也已完成。

    /// <summary>
    /// 获取行
    /// </summary>
    public dyMatrixRow GetRow(int vRowIndex)
    {
    if ((vRowIndex < 0) || (vRowIndex >= Row))
    {
    dyDebug.Log("dyMatrix : GetRow : 行数组序号超限.");
    return new dyMatrixRow(0);
    }

    dyMatrixRow lRow;
    lRow = new dyMatrixRow(this.Col);
    for (int j = 0; j < this.Col; j++)
    {
    lRow[j] = this[vRowIndex, j];
    }
    return lRow;
    }

    /// <summary>
    /// 设置行
    /// </summary>
    public void SetRow(int vRowIndex, dyMatrixRow vRow)
    {
    if ((vRowIndex < 0) || (vRowIndex >= Row))
    {
    dyDebug.Log("dyMatrix : SetRow : 行数组序号超限.");
    return;
    }

    if (Col != vRow.Dimension)
    {
    dyDebug.Log("dyMatrix : SetRow : 行数组维度不匹配.");
    return;
    }

    for (int i = 0; i < Col; i++)
    {
    this.Data[vRowIndex, i] = vRow[i];
    }
    }

    /// <summary>
    /// 获取列
    /// </summary>
    public dyMatrixCol GetCol(int vColIndex)
    {
    if ((vColIndex < 0) || (vColIndex >= Col))
    {
    dyDebug.Log("dyMatrix : SetCol : 列数组序号超限.");
    return new dyMatrixCol(0);
    }

    dyMatrixCol lCol;
    lCol = new dyMatrixCol(this.Row);
    for (int i = 0; i < this.Row; i++)
    {
    lCol[i] = this.Data[i, vColIndex];
    }
    return lCol;
    }

    /// <summary>
    /// 设置列
    /// </summary>
    public void SetCol(int vColIndex, float[] vCol)
    {
    #region 【入口校验】

    if ((vColIndex < 0) || (vColIndex >= Col))
    {
    dyDebug.Log("dyMatrix : SetCol : 列数组序号超限.");
    return;
    }

    if (vCol == null)
    {
    dyDebug.Log("dyMatrix : SetCol : 列数组为null.");
    return;
    }

    if (Row != vCol.Length)
    {
    dyDebug.Log("dyMatrix : SetCol : 列数组维度不匹配.");
    return;
    }

    #endregion
    #region 【业务逻辑】

    for (int i = 0; i < Row; i++)
    {
    this.Data[i, vColIndex] = vCol[i];
    }

    #endregion
    }

    行运算符+代码

    /// 行+行 : 对应元素相加
    public static dyMatrixRow operator+ (dyMatrixRow vMatrixRowA, dyMatrixRow vMatrixRowB)
    {
    // 矩阵行A维度与矩阵行B维度相等
    if (vMatrixRowA.Dimension != vMatrixRowB.Dimension)
    {
    dyDebug.Log("dyMatrixRow : operator+ : 维度不匹配.");
    return new dyMatrixRow(0);
    }

    dyMatrixRow lRow;
    lRow = new dyMatrixRow(vMatrixRowA);

    for (int i = 0; i < lRow.Dimension; i++)
    {
    lRow[i] += vMatrixRowB[i];
    }

    return lRow;
    }

    列运算符+代码


    /// 行-行 : 对应元素相减
    public static dyMatrixCol operator- (dyMatrixCol vMatrixColA, dyMatrixCol vMatrixColB)
    {
    // 矩阵行A维度与矩阵行B维度相等
    if (vMatrixColA.Dimension != vMatrixColB.Dimension)
    {
    dyDebug.Log("dyMatrixCol : operator+ : 维度不匹配.");
    return new dyMatrixCol(0);
    }

    dyMatrixCol lCol;
    lCol = new dyMatrixCol(vMatrixColA);

    for (int i = 0; i < lCol.Dimension; i++)
    {
    lCol[i] -= vMatrixColB[i];
    }

    return lCol;
    }

    以上,谢谢。

    2017年12月4日 15:11
  • Hi,

    感谢你的反馈。 

    我们分析datatable 的代码,它的rows代码是通过下面的方法实现的,你可以参考一下。

    [Browsable(false), ResDescriptionAttribute(Res.DataTableRowsDescr)]
            public DataRowCollection Rows {
                get {
                    return rowCollection;
                }
            }
    https://referencesource.microsoft.com/#System.Data/System/Data/DataTable.cs,8aab738ad2b51b53

    据我分析,估计你的matrix类,要有collection 这个特性,你可以参考上面DataRowCollection代码,继承相关的基类。

    Best Regards,

    Hart


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 白极熊 2017年12月5日 17:37
    2017年12月5日 9:21
    版主
  • 嗯嗯,感觉应该是这样搞的,谢谢大神解惑。

    我得赶快去研究一下咋个写。

    2017年12月5日 17:07
  • 我看了一下代码,原来是通过

    this.rowCollection = newDataRowCollection(this);

    将DataTable的引用传递到DataRowCollection里,

            internal DataRowCollection(DataTable table) {

                this.table = table;
            }
    然后直接操作数据。

    是我魔障了,都写过dyMatrixRows类(类似Collection类),但是当时是把Data[,]直接传过去,忘了直接传引用这招。

    谢谢解惑,已经知道该怎么写了。


    • 已标记为答案 白极熊 2017年12月5日 17:36
    • 取消答案标记 白极熊 2017年12月5日 17:36
    2017年12月5日 17:36