public static async Task <IBifoqlObject> Eval(Location location, QueryContext context, IBifoqlExpression expr) { return(await expr.Evaluate(context)); }
public static async Task <IBifoqlObject> ToMap(Location location, QueryContext context, IBifoqlArrayInternal list, IBifoqlExpression keyExpr, IBifoqlExpression valueExpr) { var dict = new Dictionary <string, IBifoqlObject>(); foreach (var item in list) { var target = await item(); var currContext = context.ReplaceTarget(target); var key = await keyExpr.Evaluate(currContext) as IBifoqlString; if (key == null) { return(new AsyncError(location, "Result of to_map's key expression must be a string")); } var value = await valueExpr.Evaluate(currContext); dict.Add(await key.Value, value); } return(dict.ToBifoqlMap()); }
private static async Task <IBifoqlObject> MaxMin(Location location, QueryContext context, IBifoqlArrayInternal list, IBifoqlExpression keyQuery, bool max) { var pairs = new List <KeyValuePair <IBifoqlObject, IBifoqlObject> >(); foreach (var value in list) { var val = await value(); var newContext = context.ReplaceTarget(val); var key = keyQuery == null ? val : await keyQuery.Evaluate(newContext); pairs.Add(new KeyValuePair <IBifoqlObject, IBifoqlObject>(key, val)); } var resultNum = max ? double.MinValue : double.MaxValue; string resultStr = null; bool first = true; bool isNum = false; IBifoqlObject result = null; foreach (var val in pairs) { var curr = val.Key; if (first) { first = false; isNum = curr is IBifoqlNumber; } if (isNum) { var currNumObj = curr as IBifoqlNumber; if (currNumObj == null) { return(new AsyncError(location, "To take max, all members of the list must be a number or string")); } var currNum = await currNumObj.Value; if ((max && currNum > resultNum) || (!max && currNum < resultNum)) { resultNum = currNum; result = val.Value; } } else { var currStrObj = curr as IBifoqlString; if (currStrObj == null) { return(new AsyncError(location, "To take max, all members of the list must be a number or string")); } var currStr = await currStrObj.Value; if (resultStr == null || currStr.CompareTo(resultStr) == (max ? 1 : -1)) { resultStr = currStr; result = val.Value; } } } return(result); }
public static async Task <IBifoqlObject> SortBy(Location location, QueryContext context, IBifoqlArrayInternal array, IBifoqlExpression keyExpr) { var pairs = new List <Tuple <IBifoqlObject, IBifoqlObject> >(); var values = new List <IBifoqlObject>(); foreach (var obj in array) { var currObj = await obj(); var keyObj = keyExpr == null ? currObj : await keyExpr.Evaluate(context.ReplaceTarget(currObj)); pairs.Add(Tuple.Create(keyObj, currObj)); } if (pairs.All(p => p.Item1 is IBifoqlString)) { var pairsByString = new List <Tuple <string, IBifoqlObject> >(); foreach (var item in pairs) { pairsByString.Add(Tuple.Create(await((IBifoqlString)item.Item1).Value, item.Item2)); } return(pairsByString.OrderBy(p => p.Item1).Select(p => p.Item2).ToList().ToBifoqlObject()); } else if (pairs.All(p => p.Item1 is IBifoqlNumber)) { var pairsByNumber = new List <Tuple <double, IBifoqlObject> >(); foreach (var item in pairs) { pairsByNumber.Add(Tuple.Create(await((IBifoqlNumber)item.Item1).Value, item.Item2)); } return(pairsByNumber.OrderBy(p => p.Item1).Select(p => p.Item2).ToList().ToBifoqlObject()); } else { return(new AsyncError("sort must be sorted either by number or string")); } }
public static Task <IBifoqlObject> MinBy(Location location, QueryContext context, IBifoqlArrayInternal list, IBifoqlExpression keyExpr) { return(MaxMin(location, context, list, keyExpr, max: false)); }