[SOLVED] Max 9: Array support in JS/V8 ?

Oni Shogun's icon

Hi coders,

I have been trying in Max 8 and newly in Max 9 to handle/parse (named) arrays passed from Max in JavaScript but I still cannot access their values, let alone nested arrays. Is support for Arrays in JS/V8 part of a future implementation? Or am I overlooking something very obvious?

Thank you very much for any hint!

Iain Duncan's icon

I was also wondering about this, I couldn't see anything on the Array API on this page, but I could have sworn I remember someone mentioning Max array handling in JS.

thanks

Oni Shogun's icon

I myself have asked about this/such feature at the beginning of this year:
https://cycling74.com/forums/handle-array-namespace-in-js

TFL's icon

With v8, you can receive arrays using

function msg_array(obj) {
  //do something with obj, which is a regular JS array representing your Max array
}

and send regular JS arrays as Max arrays using

outlet_array(0, obj);

where 0 is the outlet number and obj your JS array.

With the old js object, I believe you can only create Max arrays and send them as shown in the JavaScript section of this page, but you cannot parse received ones.

yaniki's icon

Yeah, this is great!

BTW. I have to admit, that semantics behind “V8” is really refreshing my sense of humor: as a big fan of the Mad Max movies I see a lot of fun in having V8 engine inside Max…

Oni Shogun's icon

Thanks TFL for the documentation hint as well as the function msg_array(obj)! After some search I eventually found the comment in the helpfile under the dictionary tab which mentions this functionality, almost surreptitiously.

The new handling of complex messages like dictionary and array in v8 seems super straight forward and more intuitive. However, I have not found a way to access the name of either an incoming array or dictionary since they don't have this property in v8. With the so-called old way the name was easily accessible as global variable/property, yet with the new way I don't seem to see any ways to retrieve it, let alone its containing values.

Also: When nested (wrapped) arrays are received, they can be parsed, though any subarray will return atomarray if it is not parsed twice. I.e., to access the wrapped subarray in obj = [0, [1,2,3], 4, 5 ], one has to access ob[1][0] (obj[1] has a length of '1', not '3'); this is then true for any further subarray too…

TFL's icon

After some search I eventually found the comment in the helpfile under the dictionary tab which mentions this functionality, almost surreptitiously.

Yes, this definitely needs to be more visible. I guess it'll be added to the documentation pages.


Also: When nested (wrapped) arrays are received, they can be parsed, though any subarray will return atomarray if it is not parsed twice. I.e., to access the wrapped subarray in obj = [0, [1,2,3], 4, 5 ], one has to access ob[1][0] (obj[1] has a length of '1', not '3'); this is then true for any further subarray too…

Weird, this is not what I see:

Max Patch
Copy patch and select New From Clipboard in Max.

I have not found a way to access the name of either an incoming array or dictionary since they don't have this property in v8

If you define a function array(a) {}, a will contain the array's name (and msg_array() won't be called). But then there isn't much you can do unfortunately. I tried to call msg_array(a) in various ways but it doesn't work sadly :( it just returns undefined.

Max Patch
Copy patch and select New From Clipboard in Max.

Oni Shogun's icon

ah great, thanks TFL. At least I know now that I had parsed the array incorrectly. Regarding the name property, it would of course be super useful to access it in codebox using the simplified msg_array function. Using the array method the name can in fact be retrieved once used as MaxArray while other functionality remains untouched:

msg_array(JSON.parse([MaxArray].stringify()))
msg_array(JSON.parse([MaxArray].stringify()))

It does seem a bit cumbersome, however, given that the v8-system is a great performance upgrade in most (other) areas…

Max Patch
Copy patch and select New From Clipboard in Max.

Thank you testing, sharing and helping!

TFL's icon

Yes, I just figured out!

function array(n) {
	post(n + " is the array's name\n");
	
	//Retrieving content
	let max_arr = new MaxArray();
	max_arr.name = n;
	
	//Converting to JS array
	js_arr = JSON.parse(max_arr.stringify());
	post(JSON.stringify(js_arr) + " is the array's content\n");
	
	//Modifying content
	js_arr[0] = 'test';
	
	//Converting to Max array
	max_arr.parse(JSON.stringify(js_arr));
        //EDIT: max_arr.set(js_arr) is more straightforward!
	
	//Output as an array message
	outlet(0, 'array', max_arr.name);

        //Passing to msg_array
	msg_array(js_arr);
}
Max Patch
Copy patch and select New From Clipboard in Max.

TFL's icon

aaaaand, you can use the replace, set, get, length, prepend, append, etc. functions available for [array] onto a MaxArray object!

Max Patch
Copy patch and select New From Clipboard in Max.

But we're still missing a proper way to convert between max and js array, or a way to get the arrays name using msg_float() and setting it with outlet_array().