ArrayBuffer文字列操作配列・連想配列

【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

書いた人(管理人):けーちゃん

スポンサーリンク

記事の内容について

null

こんにちはけーちゃんです。
説明するのって難しいですね。

「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。

掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。

ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php

 

このサイトは、リンクフリーです。大歓迎です。