пускает слюни mvel для каждого элемента на карте

Один из запретов в слюнях включает в себя ручную итерацию коллекций в последствии (затем пункт). Мне нужно написать слюни, которые эффективно перебирают карту, делая что-то для каждой пары ключ-значение на этой карте. Другими словами, мне нужно продублировать поведение цикла for-each в drools без фактического написания цикла for-each.

Теперь я понимаю, что могу просто написать цикл for-each в последствии. Я хочу, чтобы мой код был как можно ближе к стандарту drools. Ниже я привел более конкретный пример.

У меня есть карта строк и цветов.

Map<String, Color> colorMap

Для каждого цвета на карте я хочу проверить другую коллекцию, чтобы найти точный код для этого цвета.

Map<Color, ColorCode> colorCodes

Подход на диалекте Java будет примерно таким:

for (Map.Entry<String, Color> entry : colorMap.entrySet())
{
    ColorCode code = colorCodes.get(entry.getValue());

    thenconsequence.do(code);
}

Как можно было бы сделать что-то подобное, используя диалект слюней?

Обновление: чем больше я думаю об этой проблеме, тем больше меня беспокоит, что я не должен выполнять такой поиск/итерацию карты в контексте слюни. Правильный способ сделать это может состоять в том, чтобы вставить представления объектов фактов этих коллекций в рабочую память. Например, я мог бы обернуть каждый цвет в colorFact, в котором заключен цвет, и поле, указывающее имя цвета. Так же и с кодами. Я мог бы тогда пустить слюни по строкам:

when
Color(name=="blue", $c:color)
ColorCode(name == "blue", $code:colorCode)
then 
  $code.printCode();
end

Если это лучший способ сделать это, меня беспокоит огромное количество фактов, которые мне придется добавить. У меня уже есть тысячи. Это создаст еще десятки тысяч. Я не беспокоюсь о памяти. Скорее меня беспокоит время, необходимое для перебора всех этих коллекций и добавления их элементов в рабочую память. Может ли кто-нибудь прокомментировать, является ли это лучшим способом сделать это или существует лучший способ?


person melchoir55    schedule 20.03.2014    source источник


Ответы (1)


Хотя это можно сделать с помощью простого набора операторов Java, вот как это сделать с помощью одного правила с наименьшими (я думаю) затратами на вставку и т. д.:

rule "matchcolorcode"
when
    $cm: ColorMap()
    Map.Entry( $key: key, $color: value ) from $cm.entrySet()
    $ccm: ColorCodeMap( $ccm.containsKey($key) )
then
    System.out.println( $key + ": " + $color + ", " + $ccm.get($key) );
end

Факты представляют собой простые оболочки для общих экземпляров HashMap, например:

class ColorMap extends HashMap<String,Color> {}
person laune    schedule 21.03.2014