Здравствуйте, DarkGray, Вы писали:
DG>а теперь напиши полный вариант для следующей элементарной задачи:
DG>от пользователя приходит список кортежей для фильтрации и сортировки.
DG>вид кортежа фильтрации:
DG>DG>string field;
DG>string op;
DG>string value;
DG>
DG>вид кортежа сортировки:
DG>DG>string field;
DG>bool isAscElseDesc;
DG>
DG>пример запроса пользователя:
DG>DG>filters:
DG>{field:'name', op:'starts', value='василий'},
DG>{field:'birthday', op:'>=', value='10.01.1974'},
DG>{field:'company', op:'==', value='rsdn'},
DG>orders:
DG>{field:'name', isAscElseDesc:true},
DG>{field:'birthday', isAscElseDesc:false},
DG>
А за каким хреном надо было преобразовывать действия в текстовую форум? Просто формируй свои действия сразу в виде запросов и делать ничего не придется.
В худшем случае, если оставить текстовое представление, придется завести хэш-таблицу в которой смапить кортеж field * op (и field * isAscElseDesc) на соответствующую лямбду. Вот рабочий код для добавления сортировки (фильтрация делается аналогичным образом):
using Nemerle.Collections;
using System;
using System.Collections.Generic;
using System.Console;
using System.Linq;
[Record]
class Person
{
public Name : string;
public Birthday : DateTime;
public Company : string;
public override ToString() : string
{
$"Person: $Name, $Birthday, $Company"
}
}
module Program
{
data : list[Person] =
[
Person("Вася", DateTime(1976, 5, 15), "RSDN"),
Person("Петя", DateTime(1967, 3, 1), "Мега"),
Person("Петя", DateTime(1981, 1, 5), "Мега"),
Person("Петя", DateTime(1953, 1, 12), "Мега"),
Person("Аня", DateTime(1981, 12, 21), "Мега"),
Person("Дуня", DateTime(1982, 12, 21), "Мега"),
];
Main() : void
{
def myQuery = data.Where(p => p.Birthday < DateTime(1982, 1, 1)); // эмулируем основной запрос.
// orderingInfos содержит кортежи описывающие сортировки. По уму вместо
// текстового представления здесь нужно было сразу использовать список
// функций-преобразователей запросов.
def orderingInfos = [("name", true), ("birthday", false)];
def orderedMyQuery = OrderingInfosToQuery(myQuery, orderingInfos);
//orderedQuery // теперь мы имеем запрос к которому добавлены нужные методы сортировки
WriteLine($<#..$(orderedMyQuery; "\n")#>); // выводим результат на консоль разделяя строки переносом строки
_ = ReadLine();
}
// Функция пребразования списка кортежей описывающих сортировк в запрос.
OrderingInfosToQuery(query : IEnumerable[Person], orderingInfos : list[string * bool]) : IEnumerable[Person]
{
def map = Hashtable();
// map отображает один кортеж описывающий сортировку на функцию
// добавляющую эту сортировку к запросу. Функция принимает IEnumerable,
// но ничто не мешает использовать и IQueryble.
map["name", true] = (query : IEnumerable[Person]) => query.OrderBy(_.Name);
map["birthday", false] = (query : IEnumerable[Person]) => query.OrderByDescending(_.Birthday);
//...
def addOrdering(orderingInfo, query)
{
def addOrder = map[orderingInfo]; // получаем функцию добавляющую к запросу сортировку
def newQuery = addOrder(query); // трансформируем запрос
newQuery
}
def orderedQuery = orderingInfos.FoldLeft(query, addOrdering);
orderedQuery
}
}