Home > Software engineering >  JS - How map on the bytearray works?
JS - How map on the bytearray works?

Time:01-18

I was provided a function like this

function toHexString(bytes) {
    const a =  bytes.map(function (byte) {
        console.log("--------------------")
        const parsedValue = ("00"   (byte & 0xFF).toString(16)).slice(-2)
        console.log(parsedValue)
        console.log(typeof parsedValue)
        console.log("--------------------")
        return ("00"   (byte & 0xFF).toString(16)).slice(-2);
    });
    console.log(a)
}
toHexString(Buffer.from("2241f2", 'hex'))

Here is the log response of it

--------------------
22
string
--------------------
--------------------
41
string
--------------------
--------------------
f2
string
--------------------

<Buffer 16 29 00>

I actually thought it gonna provide me 2241f2 in the response but it is not. Can you guys explain it to me why is that ?

If possible, Can you re-create it with a for loop to help me understand it better ?


My try using loop

const a = Buffer.from("2241f2", 'hex')
const b= []
for (let byte of a) {
    b.push(("00"   (byte & 0xFF).toString(16)).slice(-2))
}
console.log(b)

Result

[ '22', '41', 'f2' ]

CodePudding user response:

The result of .map is always of the same type as the source, therefore, when you use Buffer.map, the object it creates will be a Buffer too and everything you return from the callback is converted back to the underlying data type, i.e. bytes.

You can observe the same behaviour with typed arrays as well:

const uint8 = new Uint8Array([1, 2, 3]);
const hellos = uint8.map(x => 'hello');
console.log(hellos); // surprise

To get a regular array from a mapper, you have to invoke Array.map specifically:

const a =  [].map.call(bytes, function (byte) {
   fine to return strings here
})

or use a loop instead:

const a = []
for (let byte of bytes)
   a.push(...convert byte to string...)

CodePudding user response:

In your mapping function you receive 'bytes' (in the sense of Buffer elements) and return strings.

However, you should preserve types here.

Change

return ("00"   (byte & 0xFF).toString(16)).slice(-2);

to

return byte & 0xff;

and everything will be fine.

If your mapping involves changing the datatypes of the elements during the mapping, expect the result to be undefined in principle - in fact it does depend on the implementation. In the node.js runtime proper you observe the behavior you describe, this substitute produces the desired output with your original code (use ethereumjs.Buffer.Buffer instead of Buffer).

  • Related