AliRıza Adıyahşi
AliRıza Adıyahşi

Reputation: 15866

How I can parse lambda select?

I am using DynamicExpressionParser but I need to parse Select method. Here is the code:

using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Text.RegularExpressions;

var categories = new List<Dictionary<string, object>>
{
    new() {{"id", 1}, {"name", "Food"}},
    new() {{"id", 2}, {"name", "Drink"}},
    new() {{"id", 3}, {"name", "Snack"}}
};

var dict = new Dictionary<string, object> {{"categories", categories}};
// var codeToGetFirstCategoryName = "Category Name: ${categories[0][\"name\"]}"; // This is working
var codeToGetNames = "Category Names: ${string.Join(\", \", categories.Select(x => x[\"name\"]))}";
var result = StringHelper.Interpolate(codeToGetNames, dict);

Console.WriteLine(result);

public static class StringHelper
{
    public static string Interpolate(string text, Dictionary<string, object> row, string pattern = @"\$\{(?<key>[^{}]*)\}")
    {
        return Regex.Replace(text, pattern, match =>
        {
            var parameterExpressions = row.Select(column => Expression.Parameter(column.Value.GetType(), column.Key));
            var lambdaExpression = DynamicExpressionParser.ParseLambda(parameterExpressions.ToArray(), typeof(object), match.Groups["key"].Value, row.Values.ToArray());

            return lambdaExpression.Compile().DynamicInvoke(row.Values.ToArray())?.ToString() ?? string.Empty;
        });
    }
}

This is returning following message:

Unhandled exception. ')' or ',' expected (at index 38)

How I can handle Select? Or completely different solution other than using dynamic expression parser?

Thanks.

Upvotes: 1

Views: 174

Answers (1)

Kenan BAŞDEMİR
Kenan BAŞDEMİR

Reputation: 67

You can use Z.Expressions.Eval package where you can use string.Join and similar methods. The example according to your project codes is arranged below:

public static string Interpolate(string text, Dictionary<string, object> row, string pattern = @"\$\{(?<key>[^{}]*)\}")
    {
        return Regex.Replace(text, pattern, match =>
        {
            //Expression is taken
            var expression = match.Groups["key"].Value;

            //The expression and parameters are sent to the eval method.
            return Eval.Execute<string>(expression, row);
        });
    }

You can check the Z.Expressions.Eval package for the library details.

Upvotes: 0

Related Questions