tags:

views:

584

answers:

7

I know how to do this using for loops. Is it possible to do something like this using LINQ or lambdas?

int[] a = { 10, 20, 30 };
int[] b = { 2, 4, 10 };
int[] c = a * b; //resulting array should be { 20, 80, 300 }
+1  A: 

You can do something like this:

int[] a = {10, 20, 30};
int[] b = {2, 4, 10};

if (a.Length == b.Length)
{
  int[] result = (from i in Enumerable.Range(0, a.Length)
          let operation = a[i]*b[i]
        select operation).ToArray();
}

But I recommend you if you will work with matrices and more advanced mathematical topics to get a good Math library, like NMath or search for a Matrix class implementation, there are many out there...

CMS
+2  A: 

There is nothing built in, but you can always write your own functions. The first one below is a simple extension method doing what you want. The second allows you to specify the function to apply:

class Program
{
    public static void Main(string[] args)
    {
        int[] a = { 10, 20, 30 };
        int[] b = { 2, 4, 10 };
        int[] c = a.MatrixMultiply(b);
        int[] c2 = a.Zip(b, (p1, p2) => p1 * p2);
    }
}

public static class Extension
{
    public static int[] MatrixMultiply(this int[] a, int[] b)
    {
        // TODO: Add guard conditions
        int[] c = new int[a.Length];
        for (int x = 0; x < a.Length; x++)
        {
            c[x] = a[x] * b[x];
        }
        return c;
    }

    public static R[] Zip<A, B, R>(this A[] a, B[] b, Func<A, B, R> func)
    {
        // TODO: Add guard conditions
        R[] result = new R[a.Length];
        for (int x = 0; x < a.Length; x++)
        {
            result[x] = func(a[x], b[x]);
        }
        return result;
    }
}
Robert Wagner
A: 

Funny enough, I answered another question today which sums numbers in place in two sequences.

Bryan Watts
Even funnier, perhaps, is that I'm actually using a Matrix library in that code now anyway...
Will Dean
A: 

Check out this MSDN article on the upcoming PLINQ (Parallel LINQ). From the article, here is an example of using PLINQ to parallelize matrix multiplication:

void ParMatrixMult(int size, double[,] m1, double[,] m2, double[,] result)
{
  Parallel.For( 0, size, delegate(int i) {
    for (int j = 0; j < size; j++) {
      result[i, j] = 0;
      for (int k = 0; k < size; k++) {
        result[i, j] += m1[i, k] * m2[k, j];
      }
    }
  });
}

It's using LINQ and a Lambda! And as a bonus it's spread across processors.

Lance Fisher
Actually it uses the Task Parallel Library (TPL) and delegates (not Lambda).
Cameron MacFarland
+3  A: 

EDIT: The code below will work, but it's not as readable as using an explicit method. LINQ is great where it definitely adds to readability... but this isn't one of those cases.

This is a briefer version of CMS's answer - the extra let isn't required, and when you're just doing a projection it's simpler to just use dot notation:

int[] result = Enumerable.Range(0, a.Length)
                         .Select(i => a[i] * b[i])
                         .ToArray();

An alternative is to use the form of Select which takes an index:

int[] result = a.Select((value, index) => value * b[index])
                .ToArray();
Jon Skeet
@Jon: surely you are not encouraging people to do it this way!
Mitch Wheat
@Mitch: Good point. Editing...
Jon Skeet
@Jon: just noticed you hit the 1000 answers mark. Nice one!
Mitch Wheat
@Mitch: Thanks. I'd been wondering exactly when it would hit...
Jon Skeet
+2  A: 

Using the Zip function (new to .NET 4.0) details here:

int[] a = { 10, 20, 30 };
int[] b = { 2, 4, 10 };

int[] c = a.Zip(b, (a1, b1) => a1 * b1).ToArray();

Until .NET 4 comes out you can use the zip implementation from the link above.

Cameron MacFarland
A: 

You know that that is actually something that Brahma would be really good at, you could do that using Linq, but then use your graphics card to do it extremely fast.

the link: http://www.ohloh.net/p/brahma-fx

gjvdkamp