Search code examples
c#arraysmultiplication

C# Multiply Each row of array by set of factors


I have a multidimensional array and I want to multiply each row of it by a single dimensional array containing factors to create a new multidimensional array. However, the number of rows in the multidimensional array will vary from one run to the next, so I'll need a way to loop the multiplication through each row of the multidimensional array until the last row is reached.

Here is a simple example, I have multidimensional array: { { 1, 2, 3, 4}, { 5, 6, 7, 8}, { 9, 10, 11, 12} }

and I want to multiply each row by: {0.5, 0.4, 0, 0.8}

to get: { { 1*0.5, 2*0.4, 3*0, 4*0.8}, { 5*0.5, 6*0.4, 7*0, 8*0.8}, { 9*0.5, 10*0.4, 11*0, 12*0.8} }

I've tried to use .Length within a for loop using the example code.

double [] factors = {0.5, 0.4, 0, 0.8};

int [,] myarray = new int [3,4] {
{ 1, 2, 3, 4},
{ 5, 6, 7, 8},
{ 9, 10, 11, 12}
};

double [] output = new double[myarray.Length];
for(int i = 0; i < myarray.Length; ++i)
    output[i] = myarray[i] * factors;

I'm getting syntax errors that extension method 'Length' cannot be applied to type int, and also indexing with [] cannot be applied to type int.


Solution

  • I'd suggest a ragged array. Multidimensional arrays exist, but are poorly supported and almost nobody uses them. If you use a jagged array, you can be more concise. More importantly, you can be more intentional about it:

    double[][] myArray = getMeSomeData();
    double[]   factors = getMeSomeRowFactors();
    
    foreach (var row in myArray)
    {
      MultiplyRow(row, factors)
    }
    
    . . .
    
    void MultiplyRow( double[] row, double[] factors )
    {
      for ( int col = 0 ; col < row.length ; ++col )
      {
        row[col] = row[col] * factors[col];
      }
    }
    

    Or even better: use Linq:

    double[][] myArray = getMeSomeData();
    double[]   factors = getMeSomeRowFactors();
    
    myArray = myArray
              .Select( row => row.Select( (cell, i) => cell * factors[i] ).ToArray() )
              .ToArray()
              ;
    

    Or even [arguably] better;

    double[][] myArray = getMeSomeData();
    double[]   factors = getMeSomeRowFactors();
    
    myArray = myArray
              .Select( Multiply(factors) )
              .ToArray()
              ;
    
    . . .
    Func<double,int,double[]> Multiply( double[] factors )
    {
      return (cell, i) => cell * factors[i];
    }