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
    Jan 23, 2012 at 3:42
  • $\begingroup$ @rcollyer, Great point. Added a clarification in my question above. Still lacking clarity? $\endgroup$
    – sblom
    Jan 23, 2012 at 3:45
  • $\begingroup$ Perfect. Exactly what I though you were asking. $\endgroup$
    – rcollyer
    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 that you have read and understand our privacy policy and code of conduct.

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