15
$\begingroup$

Using Mathematica's .NET/Link (NETLink`) package, is it possible to call out to .NET's LINQ facilities for list manipulation and other operations?

$\endgroup$
3
  • $\begingroup$ I think that there are two sides to this question: from the mathematica side and from the c# side. Could you explain which side you are asking for? As far as I can tell, from the c# side the answer is no. But, I am not familiar enough with LINQ to make a definitive answer. $\endgroup$
    – rcollyer
    Commented Jan 23, 2012 at 3:42
  • $\begingroup$ @rcollyer, Great point. Added a clarification in my question above. Still lacking clarity? $\endgroup$
    – sblom
    Commented Jan 23, 2012 at 3:45
  • $\begingroup$ Perfect. Exactly what I though you were asking. $\endgroup$
    – rcollyer
    Commented Jan 23, 2012 at 3:47

1 Answer 1

16
$\begingroup$

Yes, it is, but it's cumbersome (at least as of Mathematica 8). The hardest part is that you have to manually do a lot of the juggling required to work with .NET generics and extension methods.

For example, let's translate a straightforward solution to Project Euler's Problem #1 ("Add all the natural numbers below one thousand that are multiples of 3 or 5.") from LINQ:

Enumerable.Range(1, 999)
.Where(x => x % 5 == 0 || x % 3 == 0)
.Sum();

To .NET/Link:

(* Load stuff. *)
<< NETLink`;
InstallNET[];
LoadNETType["System.Linq.Enumerable"];

(* Create our enumerable list of numbers. *)
numbers = Enumerable`Range[1,999];

(* Create the filter that we're going to apply. *)
enumerableType = GetTypeObject[LoadNETType["System.Linq.Enumerable"]];
meths = enumerableType@GetMethods[];
whereMethod = First[Select[meths, #@Name == "Where" && Length[#@GetParameters[]] == 2&]];
intTypeParams = {GetTypeObject[LoadNETType["System.Int32"]]};
intWhereMethod = whereMethod@MakeGenericMethod[intTypeParams];
divisibleByThreeOrFive[n_] := Or[Mod[n, 3] == 0, Mod[n, 5] == 0];
whereCondition = NETNewDelegate["System.Func`2[System.Int32,System.Boolean]", divisibleByThreeOrFive];

(* Apply the filter to the list. *)
filteredNumbers = intWhereMethod@Invoke[Null, {numbers, whereCondition}];

(* Pump all the results through the filter and Sum. *)
Enumerable`Sum[filteredNumbers]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.