public override IEnumerable <Song> VisitRatioExpression([NotNull] HaGrammarParser.RatioExpressionContext context) { var expressions = context.booleanExpression(); var evaluator = new ExpressionEvaluator(); if (expressions.Length == 1) { var parsed_expression = evaluator.Visit(expressions.First()); return(library.RandomSelect(parsed_expression)); } else { var song_lists = new List <List <Song> >(); var weights = new List <int>(); double min_unit_size = double.MaxValue; for (int i = 0; i < expressions.Length; i++) { BooleanExpression parsed_expression = evaluator.Visit(expressions[i]); var list = library.RandomSelect(parsed_expression).ToList(); song_lists.Add(list); int weight = int.Parse(context.GetToken(HaGrammarLexer.NUMBER, i).GetText()); weights.Add(weight); double unit_size = list.Count / (double)weight; if (unit_size < min_unit_size) { min_unit_size = unit_size; } } var result_song_lists = new List <IEnumerable <Song> >(); for (int i = 0; i < expressions.Length; i++) { int songs_amount = (int)Math.Floor(weights[i] * min_unit_size); result_song_lists.Add(song_lists[i].Take(songs_amount)); } return(SongLibrary.Shuffle(new HashSet <Song>(result_song_lists.Aggregate((x, y) => x.Concat(y))))); } }
public QueryEvaluator(SongLibrary library) { this.library = library; }