Фильтровать и сортировать альтернативные пути в графической среде - PullRequest
0 голосов
/ 28 февраля 2020

Поскольку я не знаю, как задать вопрос напрямую, я хотел бы представить проблему шаг за шагом:

Представьте себе вектор (обтекание) объектов, и вам нужно отсортировать и отфильтровать. Обычно я делал бы что-то вроде этого:

class Foo
{
   Bar* bar
   int CalcDistance();            // operates on bar;
   std::vector<int> GetObjects(); // operates on bar;
};

std::vector<Foo*> process()
{
  std::vector<Foo*> foos = GetFoosFromSomewhere();
  std::vector<Foo*> potentialFoos;

  auto the_filter = [&](auto foo){ 
    return foo->CalcDistance() < MAGIC_NUMBER && !foo->GetObjects().empty(); 
  };
  std::copy_if(foos.begin(), foos.end(), potentialFoos.begin(), the_filter);

  auto the_sorter = [&](auto lhs, auto rhs){ return lhs->CalcDistance() > rhs->CalcDistance(); };
  std::sort(potentialFoos.begin(), potentialFoos.end(), the_sorter);

  return potentialFoos;
}

К сожалению, мне не нужно фильтровать вектор Foos. Вместо этого отдельные запросы работают с графиком и возвращают несколько результатов при задании цели (вершины на графике).

Если есть три возможности добраться до цели, вы получите три расстояния и три вектора объектов соответственно.

class Foo
{
   Bar* bar
   std::vector<int> CalcDistance(Vertex target);            // operates on bar, based on a graph;
   std::vector<std::vector<int>> GetObjects(Vertex target); // operates on bar, based on a graph;
};

Мне бы хотелось иметь простой (выразительный) способ сортировки и фильтрации альтернативных путей, ведущих к одной и той же цели. То, что я могу себе представить, выглядит примерно так:

// pseudo-code
Foo foo = GetFooFromSomewhere();
std::vector<Vertex> targets = GetTargetsFromSomewhere();

auto the_filter = [](Distance d, Objects o){ return d < MAGIC_NUMBER && !o.empty() };
auto the_sorter = [](Distances d){ return d.lhs < d.rhs; }
auto alternatives = SortAndFilter(foo, targets, 
  filter<Distance, Objects>(the_filter), 
  sorter<Distance>(the_sorter));

Я уже добился определенного прогресса, используя шаблоны c variadi и выражения сгиба для разложения отдельных объектов Query (здесь Distance и Objects) лямбд ( см. http://coliru.stacked-crooked.com/a/3a095f1adcf61de4), но это (а) не завершено, (б) не так выразительно, как хотелось бы, и (c), безусловно, «переосмысление года».

Конечная цель состоит в том, чтобы скрыть сложность вызовов базовых методов для объекта обернутой панели от конечного пользователя с возможностью расширять запросы, например, по специализации шаблона.

Проблема заключается в моих чувствах о изобретении колеса, и я почти уверен, что есть несколько лучших способов сделать это (например, некоторые полезные вещи в верхней части графика наддува).

Есть идеи (улучшения)?

...