【JavaScript】 数値配列を16進数でjoinする
更新日:2024/03/16
JavaScriptでは、数値配列に対してjoinメソッドを実行すると、10進数の文字列に変換されます。
では16進数の文字列に変換したいときはどうすればいいのでしょうか?
直接16進数で連結可能か?
Array.prototype.joinメソッドの呼び出しだけで、直接16進数で連結できないか調べてみました。
Array.prototype.joinメソッドのアルゴリズムでは、数値を文字列変換するとき10進数に変換するように定義されていました。
そのため、Array.prototype.joinメソッドの呼び出しだけで、直接16進数に変換することはできないようです。
16進数文字列の配列を作成
対処法として、数値配列をmapメソッドで16進数文字列の配列に変換したあと、joinで連結します。
const array = [0x0123,0x4567,0x89AB];
console.log( array.map( e=>e.toString(16) ).join(",") );
// 123,4567,89ab
大文字で表示したいときは、次のようにtoUpperCaseを使用します。
e.toString(16).toUpperCase()
0で桁数を統一したいときは、次のようにpadStartを使用します。
e.toString(16).padStart(4,"0")
padStartについては、こちらをご覧ください。
■【JavaScript】 ゼロやスペースで埋めして桁揃えする
8進数や32進数などもできます。
const array = [0x0123,0x4567,0x89AB];
console.log( array.map( e=>e.toString(8).toUpperCase() ).join(",") );
// 443,42547,104653
console.log( array.map( e=>e.toString(32).toUpperCase() ).join(",") );
// 93,hb7,12db
TypedArrayを16進数でjoinする
TypedArrayを16進数文字列でjoinする場合は、Arrayオブジェクトと同じ方法を使用できません。
TypedArrayについては、こちらをご覧ください。
【JavaScript】 ArrayBufferとTypedArray-メモリを確保してアクセス
TypedArrayのmapメソッドは、TypedArrayを返します。
TypedArrayには文字列を格納できないので、今回の目的には使用できないのです。
そこで最初に紹介するのが、reduceを使用した方法です。
reduceについては、こちらご覧ください。
【JavaScript】 forEach/map/filter/reduceを根本的に理解する
reduceを使用
const u16 = Uint16Array.of( 100 , 200 , 300 , 400 );
console.log(
u16.reduce(
(a,b,index)=>a + (index !== 0 ? "," : "") + b.toString(16)
,""
)
);
// 64,c8,12c,190
しかし、joinを使用していないので、今回のタイトルにはそぐわないですね。
次は、forEachで文字列配列を作成してみます。
forEachを使用
const u16 = Uint16Array.of( 100 , 200 , 300 , 400 );
console.log(
((u)=>{
const result =[];
u.forEach( e=>result.push( e.toString(16)) );
return result;
})(u16).join( "," )
);
// 64,c8,12c,190
即時関数を使用することで、無理やりメソッドチェーンしています。
無理やりついでに、ArrayオブジェクトのmapメソッドにTypedArrayを渡してみます。
Arrayオブジェクトのmapメソッドを使用
const u16 = Uint16Array.of( 100 , 200 , 300 , 400 );
console.log(
Array.prototype.map.call( u16 ,e=>e.toString(16) ).join( "," )
);
// 64,c8,12c,190
callは、メソッドのthis値を別の値に置き換えることができるメソッドです。
callについては、こちらをご覧ください。
■【JavaScript】 そろそろcall()とapply()を理解してみようと思う
Arrayオブジェクトのmapメソッドは、this値がTypedArrayでもArrayオブジェクトを生成して返してくれます。
そのため、上のコードは有効です。
ArrayBufferを16進数でjoinする
前項とあまり変わりませんが、少し汎用的にして 1バイト単位で表示する関数です。
const toHex = (view,start,length) => Array.prototype.map.call(
new Uint8Array( view.buffer ,start,length ) , e=>e.toString(16).padStart(2,"0")
).join( " " );
TypedArayを引数に渡すと、16進数テキストにして返します。
const u8Array = new Uint8Array([100,200,300]);
const u32Array = new Uint32Array([1000,2000,3000]);
console.log( toHexArrayBuffer(u8Array) ); // 64 c8 2c
console.log( toHexArrayBuffer(u32Array) ); // e8 03 00 00 d0 07 00 00 b8 0b 00 00
ビューオブジェクトのbufferプロパティを参照しているので、DataViewも受け付けます。
更新日:2024/03/16
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。