Uint8Arrayのmap関数の注意あるいはTextEncoder.encodeの戻り値の注意
Uint8Array.of(0, 1, 2).map(x => x) // Uint8Array(3) [0, 1, 2] Uint8Array.of(0, 1, 2).map(x => 0.1) // Uint8Array(3) [0, 0, 0] !? Uint8Array.of(0, 1, 2).map(x => "a") // Uint8Array(3) [0, 0, 0] !?
現在の仕様ではUint8Array.map
関数はUint8Array
型を返します。Uint8Array.map
の結果は強制的にUint8Array
の要素に変換されるため、Array.map
関数と同じ感覚で使用すると想定外の挙動が起きます。この挙動はArray.from
関数でArray
型にしてしまうことで回避できます。TextEncoder.encode
関数の戻り値(Uint8Array
型)に対してmap
関数を適用したらハマったので共有します。
Array.from関数による対処例
Array.from(Uint8Array.of(0, 1, 2)).map(x => 0.1) // [0.1, 0.1, 0.1] Array.from(Uint8Array.of(0, 1, 2)).map(x => "a") // ["a", "a", "a"]
TextEncoder.encodeにおける再現と対処
(new TextEncoder('utf-8')).encode("abc").map(ch => ch.toString(16)) // Uint8Array(3) [61, 62, 63] ※整数に変換されている。 Array.from((new TextEncoder('utf-8')).encode("abc")).map(ch => ch.toString(16)) // ["61", "62", "63"] ※文字列のまま
TextEncoder.encodeにおける再現と対処(padStart関数が無意味になる)
(new TextEncoder('utf-8')).encode("abc").map(ch => ch.toString(16).padStart(3, "0")) // Uint8Array(3) [ 61, 62, 63 ] Array.from((new TextEncoder('utf-8')).encode("abc")).map(ch => ch.toString(16).padStart(3, "0")) // Array(3) [ "061", "062", "063" ]