【问题标题】:Per-element array operation on multidimensional matrix多维矩阵上的每元素数组操作
【发布时间】:2017-02-12 20:29:48
【问题描述】:

我在 javascript 中创建一个二维矩阵,该矩阵中的每个元素都是一个空数组。

问题是,每当我尝试推送到矩阵中的某个元素时,推送都会应用于整个矩阵,而不是特定元素。

代码如下:

function createMatrix(numrows, numcols, initialValue = []) {
   var matrix = []; var row = [];
   while (numcols--) row[row.length] = initialValue;
   while (numrows--) matrix[matrix.length] = row.slice();
   return matrix;
};

function printMatrix(matrix) {
   var output = '';
   for (var i = 0; i < matrix.length; i++) {
       output += '[';
       for (var j = 0; j < matrix[i].length; j++) {
           output += '  ' + matrix[i][j];
       }
       output += '  ]\n';
   }
   console.log(output);
};

// Example code
var A = createMatrix(3,6, []);
printMatrix(A)

// This is the output:
// [              ]
// [              ]
// [              ]

// For example, we now try to add number 7 to the empty array at [1][2]
A[1][2].unshift(7);

// Let's see how the matrix looks like:
printMatrix(A)
// [  7  7  7  7  7  7  ]
// [  7  7  7  7  7  7  ]
// [  7  7  7  7  7  7  ]

上面的矩阵是错误的。推送不是仅应用于单个元素,而是应用于整个矩阵。换句话说,正确的输出应该是这样的:

// [                    ]
// [        7           ]
// [                    ]

非常感谢您的帮助。谢谢。

【问题讨论】:

    标签: javascript arrays matrix multidimensional-array


    【解决方案1】:

    您可以对行元素使用切片来获取独立元素。

    while (numrows--) matrix[matrix.length] = row.map(a => a.slice());
    //                                            ^^^^^^^^^^^^^^^^^^^
    

    function createMatrix(numrows, numcols, initialValue = []) {
       var matrix = []; var row = [];
       while (numcols--) row[row.length] = initialValue;
       while (numrows--) matrix[matrix.length] = row.map(a => a.slice());
       return matrix;
    };
    
    function printMatrix(matrix) {
       var output = '';
       for (var i = 0; i < matrix.length; i++) {
           output += '[';
           for (var j = 0; j < matrix[i].length; j++) {
               output += '  ' + matrix[i][j];
           }
           output += '  ]\n';
       }
       console.log(output);
    };
    
    // Example code
    var A = createMatrix(3,6, []);
    printMatrix(A)
    
    // This is the output:
    // [              ]
    // [              ]
    // [              ]
    
    // For example, we now try to add number 7 to the empty array at [1][2]
    A[1][2].unshift(7);
    
    // Let's see how the matrix looks like:
    printMatrix(A)

    【讨论】:

      【解决方案2】:

      第一个问题是您试图将同一初始数组 initialValue 的引用分配给具有该行的每一列:

      while (numcols--) row[row.length] = initialValue;  // <----
      

      这就是为什么所有列都填充了相同的值。 第一个问题的解决方法是:

      while (numcols--) row[row.length] = initialValue.slice();
      

      第二个问题如果您的数组包含嵌套数组,“克隆”将包含对旧数组的引用。
      这就是在这一行的矩阵行上发生的情况:

      while (numrows--) matrix[matrix.length] = row.slice();  // <---
      

      第二个问题的解决方案是使用Array.protottype.map()函数克隆所有嵌套数组:

      while (numrows--) matrix[matrix.length] = row.map(function(arr){ return arr.slice(); });
      

      现在,您将获得所需的输出:

      A[1][2].unshift(7);
      
      [              ]
      [      7        ]
      [              ]
      

      【讨论】:

        【解决方案3】:

        感谢您的 cmets 并回答大家。非常感谢。

        我也得出了同样的结论,即问题是由于 'slice()' 导致的浅拷贝。这是一个解决问题的更简单的实现,以防将来有人需要它:

        function createMatrix(dimensions) {
            var matrix = [];
        
            for (var i = 0; i < dimensions[0]; ++i)
              matrix[matrix.length] = (dimensions.length == 1 ? [] : createMatrix(dimensions.slice(1)));
        
            return matrix;
        };
        

        【讨论】:

          猜你喜欢
          • 2020-11-14
          • 2019-09-18
          • 1970-01-01
          • 1970-01-01
          • 2021-07-10
          • 1970-01-01
          • 2011-05-06
          • 1970-01-01
          • 2021-07-15
          相关资源
          最近更新 更多