Considering element-wise add / subtract / multiply / divide operation in two lists. I have the code as follows.
public class Calculate
{
public static IEnumerable<T> Add<T>(IEnumerable<T> input1, IEnumerable<T> input2)
{
return input1.Zip(input2, (first, second) => (dynamic)first + (dynamic)second).Cast<T>();
}
public static IEnumerable<T> Subtract<T>(IEnumerable<T> input1, IEnumerable<T> input2)
{
return input1.Zip(input2, (first, second) => (dynamic)first - (dynamic)second).Cast<T>();
}
public static IEnumerable<T> Multiply<T>(IEnumerable<T> input1, IEnumerable<T> input2)
{
return input1.Zip(input2, (first, second) => (dynamic)first * (dynamic)second).Cast<T>();
}
public static IEnumerable<T> Divide<T>(IEnumerable<T> input1, IEnumerable<T> input2)
{
return input1.Zip(input2, (first, second) => (dynamic)first / (dynamic)second).Cast<T>();
}
}
Tests
List<double> doubles = new List<double>();
for (int i = 0; i < 10; i++)
{
doubles.Add((double)i);
}
foreach (var element in Calculate.Add(doubles, doubles))
{
Console.WriteLine(element.ToString());
}
It just works, but dealing with dynamic
, I am wondering if it is the right way to do it? Is the code generic enough?
I suggest using generic math here, e.g.
using System.Numerics;
...
public static IEnumerable<T> Add<T>(IEnumerable<T> input1, IEnumerable<T> input2)
where T : IAdditionOperators<T, T, T> {
ArgumentNullException.ThrowIfNull(input1);
ArgumentNullException.ThrowIfNull(input2);
return input1.Zip(input2, (first, second) => first + second);
}
We can implement all the rest operations in the similar way:
public static IEnumerable<T> Subtract<T>(IEnumerable<T> input1, IEnumerable<T> input2)
where T : ISubtractionOperators<T, T, T> {
ArgumentNullException.ThrowIfNull(input1);
ArgumentNullException.ThrowIfNull(input2);
return input1.Zip(input2, (first, second) => first - second);
}
public static IEnumerable<T> Multiply<T>(IEnumerable<T> input1, IEnumerable<T> input2)
where T : IMultiplyOperators<T, T, T> {
ArgumentNullException.ThrowIfNull(input1);
ArgumentNullException.ThrowIfNull(input2);
return input1.Zip(input2, (first, second) => first * second);
}
public static IEnumerable<T> Divide<T>(IEnumerable<T> input1, IEnumerable<T> input2)
where T : IDivisionOperators<T, T, T> {
ArgumentNullException.ThrowIfNull(input1);
ArgumentNullException.ThrowIfNull(input2);
return input1.Zip(input2, (first, second) => first / second);
}