Thanks to the initial pointer from Amir Popovich, I was able (several hours later) to find the answer. As it was not very straight forward, I will put all the details here for whoever needs this in the future (including myself).
Unfortunately, the Roslyn approach (described here https://www.strathweb.com/2018/01/easy-way-to-create-a-c-lambda-expression-from-a-string-with-roslyn/), although working immediately out of the box, was very slow. I experienced an overhead of approximately 2600ms for compiling the first expression and 100ms for each expression thereafter. In the comments of that page however, one Jochen Kühner pointed out the existence of the System.Linq.Dynamic.Core package (https://github.com/StefH/System.Linq.Dynamic.Core) that could do the same job. This however did not work out of the box, and even the examples in the documentation were producing errors. After some research, I realised that there was a problem in the package available in NuGet, and one Paritosh pointed out the need to also add a newer version of a file directly to my project (see Linq Dynamic ParseLambda not resolving).
So basically to get this to work (at least in .NET Core) you need to:
1) Add the NuGet System.Linq.Dynamic.Core to your project.
2) Go to the following link and get the CSharpSamples.zip from Microsoft:
https://msdn.microsoft.com/en-us/vstudio/bb894665.aspx?f=255&MSPPError=-2147217396
3) Find the file LinqSamples\DynamicQuery\DynamicQuery\Dynamic.cs and copy it into your own project.
With the above, you should have a working environment. Then if you include the following:
using System;
using System.Linq;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Linq.Dynamic;
You can write code like this:
List<List<double>> myList = new List<List<double>>()
{
new List<double>(){ 1, 25 },
new List<double>(){ 2, 14 },
new List<double>(){ 3, 30 }
};
ParameterExpression[] x = new ParameterExpression[] { Expression.Parameter(typeof(List<double>), "x") };
Func<List<double>, bool> adultFilter = (Func<List<double>, bool>) System.Linq.Dynamic.DynamicExpression.ParseLambda(x, null, "x[1] > 18").Compile();
int adults = myList.Count(adultFilter);
Console.WriteLine("Total adults " + adults);
Note that there is a class DynamicExpression in both Linq.Expression & Link.Dynamic, hence the need to provide the full reference and have an extra long line. Also note that the above takes about 30ms to compile & run, with no extra overhead for the first expression.
You can find more details on how to use the Linq.Dynamic library here (although the writer claims the Wiki is only about 80% accurate):
https://github.com/StefH/System.Linq.Dynamic.Core/
I hope that one day the NuGet package will be fixed and the Wiki will be improved, but until then maybe these notes will be of help!