2014-09-03 45 views
1

我在文件test.js如下方法:如何从java 8中的js函数获取数组输出?

function avg(input, period) { 
var output = []; 
if (input === undefined) { 
     return output; 
} 
var i,j=0; 
for (i = 0; i < input.length- period; i++) { 
    var sum =0; 
    for (j = 0; j < period; j++) { 
     //print (i+j) 
     sum =sum + input[i+j]; 
     } 
    //print (sum + " -- " + sum/period) 
    output[i]=sum/period;   
} 

return output; 
} 

我想从Java中的数组传递给这个函数,并获得Java中的JS输出数组。 我用Java代码:

double[] srcC = new double[] { 1.141, 1.12, 1.331, 1.44, 1.751, 1.66, 1.971, 1.88, 1.191, 1.101 }; 

    try { 
     ScriptEngineManager factory = new ScriptEngineManager(); 
     ScriptEngine engine = factory.getEngineByName("nashorn"); 

     String location = "test.js"; 
     engine.eval("load(\"" + location + "\");"); 
     Invocable invocable = (Invocable) engine; 
     // double[] a = (double[]) invocable.invokeFunction("avg", srcC, 2); 

     System.out.println("obj " + invocable.invokeFunction("avg", srcC, 2)); 
    } catch (Exception ex) { 
     LOGGER.error(ex.getLocalizedMessage()); 
    } 

我能看到平均JS函数的输出,但我不知道如何从JS平均功能JS输出数组在Java中

任何支持表示赞赏。

最好的问候, 奥勒利安

回答

5

Invocable.invokeFunction返回类型实现定义。的犀牛脚本引擎返回一个实现jdk.nashorn.api.scripting.JSObject

该接口有一个方法Collection<Object> values()一个对象的一个​​实例,因此,唯一需要的变化是投的invokeFunction结果,然后提取值的集合:

JSObject obj = (JSObject)invocable.invokeFunction("avg", srcC, 2); 
Collection result = obj.values(); 
for (Object o : result) { 
     System.out.println(o); 
} 

输出:

1.1305 
1.2255 
1.3855 
1.5955 
1.7054999999999998 
1.8155000000000001 
1.9255 
1.5354999999999999 
+0

我只是看到了你的答案。比我的更好。非常感谢 – aurelianr 2014-09-03 12:53:19

2

感谢您的回复。下面的代码是更好,因为从以前的Java版本中使用java 8 JS引擎,而不是犀牛:

double[] output = {}; 
    try { 
     ScriptEngineManager factory = new ScriptEngineManager(); 
     ScriptEngine engine = factory.getEngineByName("nashorn"); 

     String locationTemp = "D:/test.js"; 
     engine.eval("load(\"" + locationTemp + "\");"); 
     Invocable invocable = (Invocable) engine; 

     ScriptObjectMirror obj = (ScriptObjectMirror) invocable.invokeFunction("avg", 
     input, period); 

     Collection<Object> values = obj.values(); 
     if (values.size() == 0) { 
      return output; 
     } 
     output = new double[values.size()]; 
     int i = 0; 
     for (Iterator<Object> iterator = values.iterator(); iterator.hasNext();) { 
      Object value = iterator.next(); 
      if (value instanceof Double) { 
       Double object = (Double) iterator.next(); 
       output[i] = object; 
      } 
     } 

    } catch (NullPointerException | NoSuchMethodException | ScriptException ex) { 
     log.error(ex.getLocalizedMessage()); 
    } 

感谢ninad他迅速回答

问候, 奥勒利安,

+0

你有Java 8 - 不需要使用显式的interator,只需使用for(Object value:values){...}'就像我在答案中所做的那样。此外,你忘了增加'我'... ;-) – Alnitak 2014-09-03 13:11:59

+0

确实......我观察到我忘了增量。再次感谢您的回答。 – aurelianr 2014-09-03 13:21:26