2

I have a list of hashmap<string, real>. I want to access each element on the list, apply a predicate on it and add the element to another list if the predicate returns true.

For example suppose I have a list of hashmap like this - {(a, 15), (b, 17), (c, 12)}, {(a, 12), (b, 13), (d, 90)}. My predicate would be something like a > 7 & b < 15 . Now I would apply this predicate on each element of the list and will find that the second element satisfy the predicate. Applying the predicate should be easy as all I have to do is to access the element and compare its value with values supplied with predicate.

The part where I am stuck is how to save such a predicate in a configuration file, such that it can be easily converted into a class and new predicates can be added without fiddling with core code.

BatScream
  • 19,260
  • 4
  • 52
  • 68
ocwirk
  • 1,079
  • 1
  • 15
  • 35
  • 2
    You're looking to convert text into an algorithm, so you're really looking for a general lexer/parser or scripting language. See [this SO question](http://stackoverflow.com/q/3422673/1426891), which discusses some libraries (including Java 6's built-in Javascript engine) and how to write your own. – Jeff Bowman Nov 11 '14 at 23:45
  • 2
    Perhaps an easier approach, if the scope of the predicates could be easily limited to a few particular cases, is to offer a set of predefined predicates, and in the configuration class use the class name and a number of parameters that work with that class. – RealSkeptic Nov 11 '14 at 23:58

1 Answers1

1

One way is to use nashorn javascript engine. Write a java script validation function for each predicate, and store it in a java script file.

function pred1(a,b)
{
    if(a>7 && b<15) return true;
    else return false;
}

Create and load the predicate file. You need to mention all the predicate file paths in a configuration file, and lookup their paths from the configuration file.

Properties property = new Properties();
property.load(configuration file path goes here);

Sample configuration file property:

predicatefileList:test1.js,...

Get the property,

String[] filePaths = ((String)property.get("predicatefileList")).split(",");

Initialize and use the script engine.

ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("nashorn");
// use filePaths here  instead of the file name.
ScriptObjectMirror s = (ScriptObjectMirror)engine.eval("load(\"test1.js" + "\");"); 

For each map in the list, call the predicate function by passing the arguments to the predicate function:

list.forEach(map->{
            System.out.println(s.call(map.get("a"), m.get("b")));
});
BatScream
  • 19,260
  • 4
  • 52
  • 68