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 '12 at 3:42
  • $\begingroup$ @rcollyer, Great point. Added a clarification in my question above. Still lacking clarity? $\endgroup$ – sblom Jan 23 '12 at 3:45
  • $\begingroup$ Perfect. Exactly what I though you were asking. $\endgroup$ – rcollyer Jan 23 '12 at 3:47
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, privacy policy and cookie policy

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