2014-09-03 72 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