Emanuele Sabetta - 11 months ago 43

C# Question

How to render this map-reduce javascript function to an equivalent c# LINQ Select-Aggregate syntax?

`/**`

* Multiply transforms into one.

*

* @param {Array} input transforms array

* @return {Array} output matrix array

*/

exports.transformsMultiply = function(transforms) {

// convert transforms objects to the matrices

transforms = transforms.map(function(transform) {

if (transform.name === 'matrix') {

return transform.data;

}

return transformToMatrix(transform);

});

// multiply all matrices into one

transforms = {

name: 'matrix',

data: transforms.reduce(function(a, b) {

return multiplyTransformMatrices(a, b);

})

};

return transforms;

};

Answer Source

The direct equivalent would look something like this:

```
public Transform TransformsMultiply(IEnumerable<Transform> transforms)
{
var matrices = transforms.Select(transform =>
transform.Name == "matrix"
? transform.Data
: transformToMatrix(transform));
return new Transform
{
Name = "matrix",
Data = matrices.Aggregate((a, b) =>
multiplyTransformMatrices(a, b));
};
}
```

Of course you will need to define the `Transform`

class and the `transformToMatrix`

and `multiplyTransformMatrices`

methods;

Though differentiating types of transforms by the `Name`

property is not idiomatic C#. It would be much better if you created an abstract base `Transform`

type and subclasses for each type of transform:

```
public abstract class Transform { /* ... */ }
public class Matrix : Transform
{
public int[,] Data { get; set; }
}
public class OtherTypeOfTransform : Transform
{
/* ... */
}
```

The first part of the method would then look like:

```
var matrices = transforms.Select(transform =>
transform is Matrix
? transform.Data
: transformToMatrix(transform));
```

But that is not very object oriented because `transformToMatrix`

needs to know how to convert each type of transform into a matrix. You should consider adding an abstract `ToMatrix`

method to the base class and implementing it in the subclasses, thereby delegating the responsibility of converting itself into a matrix to each subclass.

```
public abstract class Transform
{
public abstract Matrix ToMatrix();
}
public class Matrix : Transform
{
public int[,] Data { get; set; }
public Matrix ToMatrix() { return this; }
}
public class OtherTypeOfTransform : Transform
{
public Matrix ToMatrix()
{
// Type-specific implementation
}
}
```

After that, the implementation would look like this:

```
public Matrix TransformsMultiply(IEnumerable<Transform> transforms)
{
return new Matrix
{
Data = transforms
.Select(transform => transform.ToMatrix())
.Aggregate((a, b) => multiplyTransformMatrices(a, b));
};
}
```

Moving the multiplication into the `Matrix`

class makes this even nicer:

```
public Matrix TransformsMultiply(IEnumerable<Transform> transforms)
{
return new Matrix
{
Data = transforms
.Select(transform => transform.ToMatrix())
.Aggregate((a, b) => a.MultiplyBy(b));
};
}
```

And that's how I would convert that JavaScript into idiomatic object-oriented C# code.