1

我在文件 test.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());
    }

我能够看到avg js函数的输出,但我不知道如何从 java 中的 js avg 函数获取 js 输出数组

任何支持表示赞赏。

最好的问候, Aurelian

4

2 回答 2

7

from 的返回类型Invocable.invokeFunction是实现定义的。Nashorn 脚本引擎返回一个对象的实例,该对象实现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
于 2014-09-03T10:51:35.223 回答
2

感谢您的回复。以下代码更好,因为使用 java 8 js 引擎而不是以前的 java 版本中的 rhino:

    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的快速回答

最好的问候,奥雷利安,

于 2014-09-03T12:43:52.797 回答