Необходимо руководство по созданию дерева оценочной логической логики
Вопрос
Кажется, я не могу найти указатель в правильном направлении, я даже не уверен, какие термины мне следует исследовать, но бесчисленные часы поиска в Google, кажется, кружат меня по кругу, так что, надеюсь, коллективный улей интеллекта Стека Переполнение может помочь.
Проблема в том, что мне нужен способ фильтровать данные в том, что я могу назвать только составным логическим деревом.В настоящее время система реализует простую систему фильтрации AND.Например, предположим, что у нас есть набор данных о людях.Вы добавляете несколько фильтров, которые показывают всех людей, где (Пол = Женский) И (Возраст > 23) И (Возраст < 30) И ( Статус = Одинокий).Достаточно просто: перебирать каждый элемент, добавлять в допустимую коллекцию элементов только в том случае, если каждое условие истинно.
Проблема, с которой я сталкиваюсь, заключается в том, как мне поступить с тем, чтобы пользователь мог создавать сложные запросы, а также и/или?Я имею в виду что-то вроде дерева, где каждый узел представляет собой выражение, оценивающее его дочерние элементы как истинное или ложное.Упрощенным примером может быть фильтрация вниз до ((Пол == Мужской И Возраст == 25) ИЛИ (Пол == Женский И Статус == Одинок)) И IQ > 120.К сожалению, на данный момент я не могу придумать лучшего примера.Но как бы вы представляли этот тип дерева выражений и оценивали элементы коллекции по этим фильтрам?Какие ссылки могут помочь?Черт, какие чертовы поисковые запросы в Google могут привести в положительном направлении?!
Спасибо всем, кто может оказать любую помощь.
Вот пример составного запроса в древовидной форме с использованием набора данных о людях.
- Запрос. Покажите мне всех людей, у которых пол мужской и глаза зеленые, пол женский, глаза голубые или статус одинок.В паренной форме (пол == мужчина && eye == зеленый) || (Sex == kener && (eye == blue || status == сингл)))
Итак, в древовидной форме я думаю
o-Root Node
- And - Sex = Male
- And - Eyes = Blue
- Or - Sex = Female
- And Eyes = Blue
- Or Status = Single
Я считаю, что решение состоит в том, чтобы представить каждый узел в такой структуре данных, как
Node
{
OpType - AND or OR
ExpressionField - The field to evaluate
ExpressionOp - =, !=, >, >=, <, <=
ExpressionValue - the value to compare the field's value against
Function Evaluate() - returns a bool
}
Итак, для данного узла оцените детей, если вы являетесь узлом И, затем верните true, если ваше выражение дает значение true, и все ваши дочерние элементы AND оцениваются как true или любой дочерний элемент OR оценивается как true и выполняется рекурсия вверх.
Кажется, он удовлетворяет всем концептуальным условиям, которые я могу ему предложить, но мы это сделаем, как только я его реализую.Я опубликую реальный код позже, когда он заработает, и фотографии, которые помогут лучше описать эту проблему другим.
Решение
Ваш анализ выражения ((Пол == Мужской И Возраст == 25) OR (Пол == Женский И Статус == Одинок)) AND IQ > 120 выглядит странно.Я бы разобрал это как:
* And
* Or
* And
* ==
* Sex
* Male
* ==
* Eyes
* Blue
* And
* ==
* Sex
* Female
* ==
* Status
* Single
* >
* IQ
* 120
Тип дерева будет:
Node
{
bool evaluate ()
}
AndNode : Node
{
Node left
Node right
bool evaluate ()
{
return left.evaluate () && right.evaluate ()
}
}
// OrNode is similar
EqualsNode : Node
{
Field field
Value value
bool evaluate ()
{
return field.value () == value
}
}
// Likewise for <, >, etc
Другие советы
Запросы такого типа часто представляются как OR
редактор массива AND
статьи изд.То есть табличный формат, в котором вы читаете несколько условий. AND
прочитали вместе, а затем прочитали до OR
их.Это приводит к некоторому повторению условий, но пользователям легко читать, писать и понимать.Ваш образец ((Sex == Male AND Age == 25) OR (Sex == Female AND Status == Single)) AND IQ > 120
будет выглядеть как
Sex == Male & Age == 25 & IQ > 120
Sex == Female & Status == Single & IQ > 120
Возможно, вам захочется поискать в Google такие термины, как «исчисление предикатов» и «конъюнктивная нормальная форма».
Я должен сказать, что именно для этого создаются механизмы баз данных.Вы можете делать все, что вам нужно, с помощью заданной логики, и даже можете получить желаемый результат, но это стандартные проблемы, решаемые базами данных и SQL.Вы также можете посмотреть linq для решения в коде.
Похоже, вам нужно создать пользовательский интерфейс, позволяющий создавать простое дерево разбора.Когда вы нажмете GO, вы сможете пройтись по дереву и создать дерево выражений LINQ из этой структуры пользовательского интерфейса.Выполните запрос LINQ, а затем обработайте результаты по мере необходимости.Поэтому я бы рекомендовал вам прочитать о деревьях выражений LINQ.