Convert a byteArray into an IntegerArray using javascript - javascript

I receive a bytearray and I want to convert it into a intarray.
Is this possible in NodeJS?
Reason to do that:
A proxy receives values from a serialconnection which is a bytearray and I try to decode that and put it into a more specific JSON object.
var uint8Message = new Uint8Array(8),
output = [];
uint8Message[0] = 40;
uint8Message[1] = 40;
uint8Message[2] = 40;
uint8Message[3] = 40;
uint8Message[4] = 40;
uint8Message[5] = 40;
uint8Message[6] = 40;
uint8Message[7] = 40;
var counter = 0;
var intermediate = [];
for (var i = 0; i< uint8Message.byteLength; i++) {
if (counter < 4) {
intermediate.push(uint8Message[i]);
}
counter++;
if (counter === 3 ){
output.push(new Uint16Array(intermediate));
counter = 0;
intermediate = [];
}
}
console.log(output);
I am sending a intArray which is converted to byteArray from arduino to a NodeJS serialport handler. I want to get 8 integer values in array:
Status and value for four engines.
So in the end I want to have this:
[1,89,2,49,1,28,3,89]
Which is not complete correct with the example. But the example above is for testing.

Still not sure I understand your question correctly but if you want to convert Uint8Array to say Uint32Array you could do
const uint8Array = new Uint8Array(8).fill(40)
console.log(new Uint32Array(uint8Array.buffer))
If you need plain old js array you could do
const uint8Array = new Uint8Array(8).fill(40)
const intArray = Array.from(new Uint32Array(uint8Array.buffer))
console.log(Array.isArray(intArray))
Also you might want to take a look at what is called DataView that allows low level access to buffers' contents.

Related

Push data in array in specific case

I am trying to push data in array with in specific indice.
At first, I have an empty array: []
After receiving data from web socket (number), example number = 4, I want to push this number into the Array at position 4.
Output: [null,null,null,null,4]
Or I can't put anything else than null like : "-"
New output: [-,-,-,-,4]
After receiving second data from web socket, example number = 2.
New output: [-,-,2,-,4]
I tried this:
let tArray = [];
for(let i=0; i<number + 1; i++){
if(i == number){
tArray[i].push(number);
}
if(!tArray[i]){
tArray[i].push("-");
}
}
You can just create an array of your desired size, fill it with "-" and then at your specific location, set the number:
const number = 2, maxSize = 4;
const tArray = new Array(maxSize).fill('-');
tArray[number] = number;
console.log(tArray);
Create an array of pre-defined size and then put data inside the array
let data = 4;
let size = 10; // as much as you like
let array = new Array(size).fill('-');
// now when the data comes from the web socket you can simply put inside the array
array[data - 1] = data;
console.log(array)
This should work for you:
const tArray = [];
if (tArray.length < number+1) {
while (tArray.length < number+1) {
tArray.push('-');
}
}
tArray[number] = number;
Your code should be fine too if you change the tArray[i].push() part in tArray.push().
Concat the current array(tArray) with a new Array with length equalse to:
Your Number (and position) - current array length + 1
this has
to happend only if current array(tArray) is no big enough
var tArray = [];
var pushIntoTarray = function (number) {
if (tArray.length < number) {
tArray = tArray.concat(new Array(number - tArray.length + 1).fill("-"));
}
tArray[number] = number;
console.log(tArray);
}
pushIntoTarray(4);
pushIntoTarray(2);
pushIntoTarray(1);
pushIntoTarray(10);

How to send transferrable object from web worker to parent in javascript?

In JS, I made a web worker, and want to send a transferable object back to parent.
In the web worker, I have
var NUMS = new ArrayBuffer(3);
NUMS[0] = 10;
NUMS[1] = 11;
NUMS[2] = 12;
postMessage(NUMS, [NUMS]);
Then in the main thread, I have
worker.onmessage = function(e) {
var first = e.data[0]; // undefined but the bytelength is 3
}
but what happens is all the values of the array buffer seems to be cleared or invalid. Does anyone know how to fix this?
Turns out you need to use one of the typed arrays
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays
var NUMS = new Int16Array(3);
NUMS[0] = 10;
NUMS[1] = 11;
NUMS[2] = 12;
postMessage(NUMS.buffer, [NUMS.buffer]);
then you can get it by
worker.onmessage = function(e) {
var a = new Int16Array(e.data);
var first = a[0];
}

Copy array --> stack or heap overflow?

I have an array named globalArrayAllTrades as you see below. I simply like to INVERT the date in a new copy of the array. So I loop through, create a new object and add it to the new array - simple.
Then function does exactly as expected. BUT if the array contains too many objects the code fails with a "FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory".
My laptop has 8 GB of memory...When the NODEJS process crashes it uses about 1.5 GB and about 70% of of totally amount of available memory is used.
I do run the NODEJS app with the parameter: --max_old_space_size=5000 which normally fixes every thing. But not this one and i have tried MANY different ways to code the same function - BUT each and every time - it fails...unless the original array is smaller.
How can I fix this issue?
function invertTrades(){
var original = globalArrayAllTrades.slice();
globalArrayAllTrades.length = 0;
globalListAllTrades.length = 0;
for(var i = 0; i < original.length; i++){
var objS = original[i];
var objE = original[original.length-1-i];
var objInv = new TradePoint(objS.number, objS.matchdate, objE.price, objE.size, objE.issell);
globalArrayAllTrades.push(objInv);
globalListAllTrades[objInv.matchdate] = objInv;
}
}
You can save some memory by making original just contain the properties you need to invert, not the whole TradePoint object. Then you don't need to construct new TradePoint objects, you can modify them in place.
var original = globalArrayAllTrades.map(function(trade) {
return {
trade.price,
trade.size,
trade.issell
};
}).reverse();
globalArrayAllTrades.forEach(function(trade, i) {
trade.price = original[i].price;
trade.size = original[i].size;
trade.issell = original[i].issell;
});
And since all the objects were modified in place, there's no need to update globalListAllTrades.
Another way is to swap the price, size, and issell properties in place between the pairs of elements:
var midpoint = Math.floor(globalArrayAllTrade.length/2);
for (var i = 0; i < midpoint; i++) {
var objS = globalArrayAllTrades[i];
var objE = globalArrayAllTrades[globalArrayAllTrades.length-1-i];
var temp = objS.price;
objS.price = objE.price;
objE.price = temp;
temp = objS.size;
objS.size = objE.size;
objE.size = temp;
temp = objS.issell;
objS.issell = objE.issell;
objE.issell = temp;
}
Have you considered just doing this?
// Copy array and then reverse it
var newArray = [].concat(original).reverse();
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse
I would suggest avoiding to copy that array:
function getInverse(i) {
var objS = globalArrayAllTrades[i];
var objE = globalArrayAllTrades[globalArrayAllTrades.length-1-i];
var objInv = new TradePoint(objS.number, objS.matchdate, objE.price, objE.size, objE.issell);
globalListAllTrades[objInv.matchdate] = objInv;
return objInv;
}
function invertTrades(){
globalListAllTrades.length = 0;
for (var i = 0, l = Math.floor(globalArrayAllTrades.length/2); i < l; i++) {
var j = globalArrayAllTrades.length-1-i;
var a = getInverse(i);
var b = getInverse(j);
globalArrayAllTrades[i] = a;
globalArrayAllTrades[j] = b;
}
}

how to convert object to binary string

Here is how I compress binary string (char codes above 255) with pako:
var charData = xhr.responseText.split('').map(function(x){return x.charCodeAt(0);});
var binData = new Uint8Array(charData);
var data = pako.deflate(binData, {level:"9"});
Here is how I decompress data back:
var data2 = pako.inflate(xhr.responseText);
Now, how can I get original string in JavaScript from this object?
I tried methods like this:
A.
pako.inflate(xhr.responseText, {to:"string"});
B.
String.fromCharCode.apply(null, data2);
C.
for (var i = 0, l = data2.length; i < l; i++)
{
result += String.fromCharCode(parseInt(array[i], 2));
}
All of these methods bring different data as JavaScript string than original.
When I save decompressed pako.inflate(xhr.responseText) to a file (using functions with a.download) then dempressed file has exactly the same bytes as original file (so compression and decompression works correctly, without any byte modification).
I am just trying to do the same and found a way to convert Object to binary string and vice versa. I just create a two function that converts JSON Object to Binary String and Binary String to JSON Object viz. covertObjectToBinary and convertBinaryToObject.
let obj = {a:1}
function covertObjectToBinary(obj) {
let output = '',
input = JSON.stringify(obj) // convert the json to string.
// loop over the string and convert each charater to binary string.
for (i = 0; i < input.length; i++) {
output += input[i].charCodeAt(0).toString(2) + " ";
}
return output.trimEnd();
}
function convertBinaryToObject(str) {
var newBin = str.split(" ");
var binCode = [];
for (i = 0; i < newBin.length; i++) {
binCode.push(String.fromCharCode(parseInt(newBin[i], 2)));
}
let jsonString = binCode.join("");
return JSON.parse(jsonString)
}
console.log('covertObjectToBinary =>', covertObjectToBinary(obj))
console.log('convertBinaryToObject =>', convertBinaryToObject(covertObjectToBinary(obj)))

Find min and max value in csv file

Looking to extend my javascript object, I want to find the minium and maximum of a multicolumn csvfile. I have looked up solutions but I cannot really grasp the right way. I found a solution here: Min and max in multidimensional array but I do not get an output.
My code that I have for now is here:
function import(filename)
{
var f = new File(filename);
var csv = [];
var x = 0;
if (f.open) {
var str = f.readline(); //Skips first line.
while (f.position < f.eof) {
var str = f.readline();
csv.push(str);
}
f.close();
} else {
error("couldn't find the file ("+ filename +")\n");
}
for (var i=(csv.length-1); i>=0; i--) {
var str = csv.join("\n");
var a = csv[i].split(","); // convert strings to array (elements are delimited by a coma)
var date = Date.parse(a[0]);
var newdate = parseFloat(date);
var open = parseFloat(a[1]);
var high = parseFloat(a[2]);
var low = parseFloat(a[3]);
var close = parseFloat(a[4]);
var volume = parseFloat(a[5]);
var volume1000 = volume /= 1000;
var adjusted_close = parseFloat(a[6]);
outlet(0, x++, newdate,open,high,low,close,volume1000,adjusted_close); // store in the coll
}
}
Edit
What if, instead of an array of arrays, you use an array of objects? This assumes you're using underscore.
var outlet=[];
var outletkeys=['newdate','open','high','low','close','volume','volume1000','adjusted_close'];
for (var i=(csv.length-1);i>0; i--) {
var a = csv[i].split(",");
var date = Date.parse(a[0]);
var volume = parseFloat(a[5],10);
outlet.push( _.object(outletkeys, [parseFloat(date,10) , parseFloat(a[1],10) , parseFloat(a[2],10) , parseFloat(a[3],10) , parseFloat(a[4],10) , parseFloat(a[5],10) , volume /= 1000 , parseFloat(a[6],10) ]) );
}
Then the array of the column 'open' would be
_.pluck(outlet,'open');
And the minimum it
_.min(_.pluck(outlet,'open'));
Edit2
Let's forget about underscore for now. I believe you need to get the maximum value on the second column, which is what you put in your open variable.
¿Would it help if you could have that value right after the for loop? For example
var maxopen=0;
for (var i=(csv.length-1); i>=0; i--) {
var a = csv[i].split(",");
var date = Date.parse(a[0]);
var newdate = parseFloat(date);
var open = parseFloat(a[1]);
maxopen=(open>maxopen)? open : maxopen; // open overwrites the max if it greater
...
...
outlet(0, x++, newdate,open,high,low,close,volume1000,adjusted_close);
}
console.log('Maximum of open is',maxopen);

Categories