This project has moved. For the latest updates, please go here.

Convert .net IEnumerable<T> to JS array

Mar 30 at 10:43 AM
Hi,

I have a JS script, which I cannot change and I need to execute it to get a result. I successfully passed some objects into the engine but I have a problem with arrays. Since I have no control over the script itself, the input objects have to be converted into compatible JS objects.

How can I convert .net array into JS array without modification of the script?

Inside the script I have to be able to access the array.length property, but .net Array, which is passed in has Array.Length property (and misses another functions).

Thank you
Petr
Coordinator
Mar 30 at 4:35 PM
Hello Petr,

How can I convert .net array into JS array without modification of the script?

You can use the script engine as a helper. Here's a simple extension method that converts a .NET collection to a JavaScript array:
internal static class EnumerableExtensions {
    public static object ToScriptArray<T>(this IEnumerable<T> collection, ScriptEngine engine) {
        dynamic array = engine.Evaluate("([])");
        foreach (var item in collection) {
            array.push(item);
        }
        return array;
    }
}
And here's how you might use it:
var foo = Enumerable.Range(100, 10);
engine.Script.foo = foo.ToScriptArray(engine);
engine.Execute(@"
    for (var i = 0; i < foo.length; ++i) {
        var item = foo[i];
        // do something
    }
");
Another possibility might be to use a wrapper to make your collection look more like a JavaScript array:
public class ArrayLikeWrapper : ArrayList {
    public ArrayLikeWrapper(IEnumerable collection) {
        foreach (var item in collection) {
            Add(item);
        }
    }
    public int length => Count;
    public int push(object item) {
        return Add(item) + 1;
    }
}
And then:
var foo = Enumerable.Range(100, 10);
engine.Script.foo = new ArrayLikeWrapper(foo);
// etc.
So there's more than one way to do it.

Good luck!
Marked as answer by pzajic on 4/3/2017 at 12:43 AM
Mar 31 at 2:14 PM
Thank you very much. Since I need to be maximally compatible with JS, I chose the first option and it works.