Using Mathematica's .NET/Link (NETLink`
) package, is it possible to call out to .NET's LINQ facilities for list manipulation and other operations?
-
$\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$– rcollyerJan 23, 2012 at 3:42
-
$\begingroup$ @rcollyer, Great point. Added a clarification in my question above. Still lacking clarity? $\endgroup$– sblomJan 23, 2012 at 3:45
-
$\begingroup$ Perfect. Exactly what I though you were asking. $\endgroup$– rcollyerJan 23, 2012 at 3:47
1 Answer
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]