Re[16]: Веб и динамика? Веб и статика+метапрограммирование.
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.12.10 07:44
Оценка:
Здравствуйте, 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
    }
}
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.