型付き配列(TypedArray)
- 型付き配列(TypedArray)とは
- 型付き配列の作成
- 配列の長さ
- ArrayBuffer の情報
- 型付き配列のループ
- 配列の検査
- typedArray.indexOf(elm)
- typedArray.lastIndexOf(elm)
- typedArray.includes(elm)
- index in typedArray
- typedArray.every(func, thisArg)
- typedArray.some(func[, thisArg])
- typedArray.find(func, thisArg)
- typedArray.findLast(func, thisArg)
- typedArray.findIndex(func, thisArg)
- typedArray.findLastIndex(func, thisArg)
- 配列要素の取り出しと追加
- 配列の並べ替え
- 配列から文字列への変換
- 配列要素の変更
- 分割代入
型付き配列(TypedArray)とは
下記の型付き配列の総称です。プログラムでは TypedArray
を使用するのではなく、下記のいずれかを使用します。
型 | 値の範囲 | サイズ (バイト数) | Web IDL 型 |
---|---|---|---|
Int8Array | -128 から 127 | 1 | byte |
Uint8Array | 0 から 255 | 1 | octet |
Uint8ClampedArray | 0 から 255 | 1 | octet |
Int16Array | -32768 から 32767 | 2 | short |
Uint16Array | 0 から 65535 | 2 | unsigned short |
Int32Array | -2147483648 から 2147483647 | 4 | long |
Uint32Array | 0 から 4294967295 | 4 | unsigned long |
Float16Array | -65504 から 65504 | 2 | なし |
Float32Array | -3.4E38 から 3.4E38 および 1.2E-38 (最小の正の数) | 4 | unrestricted float |
Float64Array | -1.8E308 から 1.8E308 および 5E-324 (最小の正の数) | 8 | unrestricted double |
BigInt64Array | -263 to 263 - 1 | 8 | bigint |
BigUint64Array | 0 to 264 - 1 | 8 | bigint |
Uint8ClampedArray
は固定されたという意味を持つ配列です。0~255 以外の値を格納する場合、Uint8Array
は下位8バイトの値が格納されますが、Uint8ClampedArray
は 0 以下であれば 0、255 以上であれば 255 が格納されます。
型付き配列の作成
new TypedArray()
引数を省略すると要素数0個の型付き配列を作成します。
const arr = new Int16Array();
new TypedArray(length)
数値を指定すると指定した個数の要素を持つ型付き配列を作成します。
const arr = new Int16Array(3); arr[0] = 10; arr[1] = 20; arr[2] = 30;
new TypedArray(iterableObject)
配列を指定すると配列の各要素を要素とする型付き配列を作成します。
const arr = new Int16Array([1, 2, 3]);
Set
など、反復可能オブジェクトを指定しても各要素を要素とする型付き配列を作成します。
const set = new Set([1, 2, 3]); const arr = new Int16Array(set);
他の型付き配列を引数にすることもできます。要素のビット数が小さくなる場合、あふれたビットは捨てられます。
const arr1 = new Int16Array([1, 2, 3]); const arr2 = new Int16Array(arr1);
new TypedArray(buffer, offset, length)
上記までの例では、型付き配列が使用する実メモリとして ArrayBuffer
を内部で自動生成します。buffer
を指定することで、別に作成した ArrayBuffer
や SharedArrayBuffer
を使用した型付き配列を作成することもできます。下記の例ではまず 6 バイトの ArrayBuffer
を確保し、これを2バイト×3要素からなる Int16Array
型付き配列にマッピングしています。
const buffer = new ArrayBuffer(6); const arr = new Int16Array(buffer);
offset
(バイト数)と length
(要素数)を指定することもできます。下記の例では 12 バイトの ArrayBuffer
を確保し、前半の 6 バイトを arr1 に、後半の 6 バイトを arr2 にマッピングしています。length
を省略した場合の残りのバイト数がすべて割り当てられます。
const buffer = new ArrayBuffer(12); const arr1 = new Int16Array(buffer, 0, 3); // オフセット0バイト目から3要素 const arr2 = new Int16Array(buffer, 6); // オフセット6バイト目から残り個数分
バッファーがリサイズ可能な場合、length
を指定していると型付き配列の要素数は変動しませんが、length を指定していない場合、バッファーサイズの変更により要素数も変動します。
const buffer = new ArrayBuffer(6, { maxByteLength: 12 }); const arr = new Int16Array(buffer); // 6バイト分3要素マッピングされる console.log(arr.length); // => 要素数は3 buffer.resize(12); // バッファサイズを6バイトから12バイトにリサイズ console.log(arr.length); // => 要素数が3から6に変わる
TypeArray.from(arrayLike, mapFn, thisArg)
配列、型付き配列、Set、文字列などの反復可能オブジェクト arrayLike
から型付き配列を作成します。
arr = Int16Array.from([1, 2, 3]); // 配列 arr = Int16Array.from(new Int16Array([1, 2, 3])); // 型付き配列 arr = Int16Array.from(new Set([1, 2, 3])); // Set arr = Int16Array.from("123"); // 文字列
mapFn
は省略可能で、指定する場合は初期化時に各要素に対して実行する関数を指定します。下記の例では 1, 2, 3 の 2倍にインデックス値 i
を加えた 2, 5, 8 の要素を持つ型付き配列が作成されます。
const arr = Int16Array.from([1, 2, 3], (v, i) => v * 2 + i);
thisArg
も省略可能で、指定する場合は mapFn
の中で this
として参照されるオブジェクトを指定します。下記の例では thisArg
として文字から数値への変換マッピング map
を渡しています。アロー関数を用いると this
の対象が変わるのでうまく動きません。
const map = { "A": 1, "B": 2, "C": 3 } const arr = Uint8Array.from(["A", "B", "C"], function (v) { return this[v]; }, map);
TypedArray.of(e1, e2, ...)
引数配列を要素とする型付き配列を作成します。
const arr = Uint8Array.of(1, 2, 3);
配列の長さ
typedArray.length
型付き配列要素の個数を返します。代入はできません。
const arr = new Int16Array([1, 2, 3]);
console.log(arr.length); // => 3
TypedArray.BYTES_PER_ELEMENT
ひとつの要素が使用するバイト数を返します。
console.log(Int16Array.BYTES_PER_ELEMENT); // => 3
ArrayBuffer の情報
typedArray.buffer
型付き配列要素に割り当てられた ArrayBuffer を返します。
const buffer = new ArrayBuffer(6);
const arr = new Int16Array(buffer);
console.log(arr.buffer); // => ArrayBuffer(6)
typedArray.byteLength
型付き配列要素に割り当てられた ArrayBuffer のバイト数を返します。
const buffer = new ArrayBuffer(6);
const arr = new Int16Array(buffer);
console.log(arr.byteLength); // => 6
typedArray.byteOffset
型付き配列要素に割り当てられた ArrayBuffer のオフセット(バイト数)を返します。
const buffer = new ArrayBuffer(12);
const arr = new Int16Array(buffer, 4, 3);
console.log(arr.byteOffset); // => 4
型付き配列のループ
for (...)
型付き配列は for
文で回すことができます。
const arr = new Int16Array([1, 2, 3]); for (var i = 0; i < arr.length; i++) { console.log(arr[i]); }
const arr = new Int16Array([1, 2, 3]); for (var i in arr) { console.log(arr[i]); }
const arr = new Int16Array([1, 2, 3]); for (var n of arr) { console.log(n); }
typedArray.forEach(fn, thisArg)
各要素に対して関数 fn
を実行します。v
は要素の値、i
はインデックスを示します。
const arr = new Int16Array([1, 2, 3]); arr.forEach((v, i) => { console.log(`index: ${i}, value: ${v}`); });
thisArg
は省略可能で、関数の中で this
として参照されるオブジェクトを指定します。アロー関数では this
は関数外スコープの this
となるので function
を使用してください。
const map = new Map([[1, "A"], [2, "B"], [3, "C"]]); const arr = new Int16Array([1, 2, 3]); arr.forEach(function(v, i) { console.log(`index: ${i}, value: ${v}, map: ${this.get(v)}`); }, map);
typedArray.entries()
key
と value
からなる反復可能オブジェクトを返します。
const arr = new Int16Array([100, 200, 300]); for (var e of arr.entries()) { console.log(`key:${e[0]} value:${e[1]}`); }
typedArray.keys()
key
の反復可能オブジェクトを返します。
const arr = new Int16Array([100, 200, 300]); for (var key of arr.keys()) { console.log(`key:${key} value:${arr[key]}`); }
typedArray.values()
value
の反復可能オブジェクトを返します。
const arr = new Int16Array([100, 200, 300]); for (var value of arr.values()) { console.log(`value:${value}`); }
typedArray.map(func, thisArg)
型付き配列の各要素に対して関数 func
を実行し、その戻り値を要素とする配列を返します。thisArg は省略可能で、関数内で this
として参照される値です。関数の引数には、要素値(value
)、要素のインデックス(index
)、型付き配列自体(array
)が渡されます。下記の例は、配列の各要素を2倍にした型付き配列を返します。
const arr1 = new Int16Array([1, 2, 3]);
const arr2 = arr1.map((value, index, array) => value * 2);
console.log(arr2); // => Int16Array(3) [2, 4, 6]
typedArray.reduce(func, initial)
配列の各要素に対して関数 func
を実行します。関数の引数には、アキュムレータ(acc
)、要素値(value
)、要素のインデックス(index
)、配列自体(array
) が渡されます。initial
を指定した場合、1回目の関数呼び出し時の acc
の値は initial
となります。initial
を省略した場合、最初の要素に対する関数は呼ばれず、最初の要素の値を acc
として 2個目の要素に対する関数が呼ばれます。次回以降は関数の戻り値を acc
として次の要素に対する関数が呼ばれ、最後の要素に対する関数の戻り値が reduce()
の戻り値となります。下記の例では各要素を2倍した合計を求めています。
const arr = new Int16Array([100, 200, 300]); const n = arr.reduce((acc, value, index, array) => { console.log(`acc:${acc} value:${value} index:${index} array:${array}`); return acc + value * 2; }, 0); console.log(n); // => acc: 0 value:100 index:0 array:100,200,300 // => acc: 200 value:200 index:1 array:100,200,300 // => acc: 600 value:300 index:2 array:100,200,300 // => 1200
initial
の 0 を指定しない場合は、100 + 200*2 + 300*2 = 1100
となり、1200 とはならない点に注意してください。
const arr = new Int16Array([100, 200, 300]); const n = arr.reduce((acc, value, index, array) => { console.log(`acc:${acc} value:${value} index:${index} array:${array}`); return acc + value * 2; }); console.log(n); // => acc: 100 value:200 index:1 array:100,200,300 // => acc: 500 value:300 index:2 array:100,200,300 // => 1100
typedArray.reduceRight(func, initial)
要素を右から順に処理していく以外は reduce()
と同様です。
const arr = new Int16Array([100, 200, 300]); const n = arr.reduceRight((acc, value, index, array) => { console.log(`acc:${acc} value:${value} index:${index} array:${array}`); return acc + value * 2; }, 0); console.log(n); // => acc:0 value:300 index:2 array:100,200,300 // => acc:600 value:200 index:1 array:100,200,300 // => acc:1000 value:100 index:0 array:100,200,300 // => 1200
配列の検査
typedArray.indexOf(elm)
配列の中に elm
とマッチする要素が最初に出現するインデックスを返します。見つからない場合は -1 を返します。
const arr = new Int16Array([100, 200, 300]);
console.log(arr.indexOf(300)); // => 2
typedArray.lastIndexOf(elm)
配列の中に elm
とマッチする要素が最後に出現するインデックスを返します。見つからない場合は -1 を返します。
const arr = new Int16Array([3, 5, 8, 5, 1]);
console.log(arr.lastIndexOf(5)); // => 3
typedArray.includes(elm)
elm
にマッチする要素の有無を true/false で返却します。
const arr = new Int16Array([100, 200, 300]); console.log(arr.includes(200)); // => true console.log(arr.includes(400)); // => false
index in typedArray
該当のインデックスの要素が存在するかどうかを調べるには index in typedArray
を用います。
const arr = new Int16Array([100, 200, 300]); console.log(2 in arr); // => true console.log(3 in arr); // => false
typedArray.every(func, thisArg)
配列の各要素に対して関数 func
を実行し、func の戻り値がすべて真であれば、true
を、さもなくば false
を返します。thisArg
は省略可能で、関数の中で this
として参照される値を指定することができます。関数の引数には、要素値(value
)、要素のインデックス(index
)、配列自体(array
)が渡されます。下記の例は、配列要素がすべて 80以上であるかを確認しています。
const arr = new Int16Array([69, 87, 93, 65, 88]);
const bool = arr.every((value, index, array) => {
return (value >= 80);
});
console.log(bool); // => false
typedArray.some(func[, thisArg])
配列の各要素に対して関数 func
を実行し、func の戻り値がひとつでも真であれば、true
を、さもなくば false
を返します。thisArg
は省略可能で、関数の中で this
として参照される値を指定することができます。関数の引数には、要素値(value
)、要素のインデックス(index
)、配列自体(array
)が渡されます。下記の例は、配列要素がひとつでも 80以上であるかを確認しています。
const arr = new Int16Array([69, 87, 93, 65, 88]);
const bool = arr.some((value, index, array) => {
return (value >= 80);
});
console.log(bool); // => true
typedArray.find(func, thisArg)
配列の各要素に対して関数 func
を実行し、func の戻り値がはじめて真となる要素の値を返します。見つからない場合は undefined
を返します。thisArg
は省略可能で、関数の中で this
として参照される値を指定することができます。関数の引数には、要素値(value
)、要素のインデックス(index
)、配列自体(array
)が渡されます。下記の例は、配列要素のうち 80 以上である要素の値を返します。
const arr = new Int16Array([69, 87, 93, 65, 88]);
const n = arr.find((value, index, array) => value >= 80);
console.log(n); // => 87
typedArray.findLast(func, thisArg)
find()
とほぼ同様ですが、配列の最後から前方に向かって検索する点が異なります。
const arr = new Int16Array([69, 87, 93, 65, 88]);
const n = arr.findLast((value, index, array) => value >= 80);
console.log(n); // => 88
typedArray.findIndex(func, thisArg)
find()
とほぼ同様ですが、値ではなくインデックスを返すことと、見つからなかった場合に -1
を返す点が異なります。
const arr = new Int16Array([69, 87, 93, 65, 88]);
const index = arr.findIndex((value, index, array) => value >= 80);
console.log(index); // => 1
typedArray.findLastIndex(func, thisArg)
findLast()
とほぼ同様ですが、値ではなくインデックスを返すことと、見つからなかった場合に -1
を返す点が異なります。
const arr = new Int16Array([69, 87, 93, 65, 88]);
const index = arr.findLastIndex((value, index, array) => value >= 80);
console.log(index); // => 4
配列要素の取り出しと追加
typedArray.at(n)
配列の n 番目(0~)の要素を取り出します。負数を指定すると最後から数えて n番目(1~)の要素を取り出します。
const arr = new Int16Array([100, 200, 300]); consolg.log(arr.at(0)); // => 100 console.log(arr.at(1)); // => 200 console.log(arr.at(-1)); // => 300
typedArray.slice(start, end)
0 から数えて start
番目から end - 1
番目までの要素を抜き出した新たな型付き配列を返します。end
を省略した場合は最後までの要素を返します。typedArray は変化しません。元の typedArray と新たな型付き配列で ArrayBuffer の共有も行いません。
const arr = new Int16Array([100, 200, 300, 400, 500, 600]);
console.log(arr.slice(2, 5)); // => Int16Array(3) [300, 400, 500]
console.log(arr);
typedArray.subarray(start, end)
0 から数えて start
番目から end - 1
番目までの要素を抜き出した新たな型付き配列を返します。end
を省略した場合は最後までの要素を返します。元の typedArray と新たな型付き配列で ArrayBuffer を共有します。片方を変更すると他方の値も変更されます。
const arr1 = new Int16Array([100, 200, 300, 400, 500, 600]); arr2 = arr1.subarray(2, 5); console.log(arr1); // => Int16Array(6) [100, 200, 300, 400, 500, 600] console.log(arr2); // => Int16Array(3) [300, 400, 500]
typedArray.filter(func, thisArg)
配列の各要素に対して関数 func
を実行し、func の戻り値が真となる要素からなる新たな型付き配列を返します。見つからない場合は空配列を返します。thisArg
は省略可能で、関数の中で this
として参照される値を指定することができます。関数の引数には、要素値(value
)、要素のインデックス(index
)、配列自体(array
)が渡されます。下記の例は、配列要素のうち 80 以上である要素からなる型付き配列を返します。
const arr1 = new Int16Array([69, 87, 93, 65, 88]);
const arr2 = arr1.filter((value, index, array) => value >= 80);
console.log(arr2); // => Int16Array(3) [87, 93, 88]
配列の並べ替え
typedArray.sort(func)
typedArray をソートしてその結果の配列を返します。typedArray 自身もソートされます。
const arr = new Int16Array([3, 7, 8, 1]); console.log(arr.sort()); // => Int16Array(4) [1, 3, 7, 8] console.log(arr); // => Int16Array(4) [1, 3, 7, 8]
ソート関数 func
を指定することもできます。ソート関数では等しければ 0 を、小さければ負の値を、大きければ正の値を返します。下記の例では大きな値順にソートしています。
const arr = new Int16Array([3, 7, 8, 1]);
arr.sort((a, b) => (a == b) ? 0 : (a < b) ? 1 : -1);
console.log(arr); // => Int16Array(4) [8, 7, 3, 1]
typedArray.toSorted(func)
typedArray をソートしてその結果の配列を返します。typedArray 自身はソートされません。他の機能は sort()
と同様です。
const arr = new Int16Array([3, 7, 8, 1]); console.log(arr.toSorted()); // => Int16Array(4) [1, 3, 7, 8] console.log(arr); // => Int16Array(4) [3, 7, 8, 1]
typedArray.reverse()
typedArray を逆順に並べ替えてその結果の配列を返します。typedArray 自身も並べ替えられます。
const arr = new Int16Array([1, 2, 3]); console.log(arr.reverse()); // => Int16Array(3) [3, 2, 1] console.log(arr); // => Int16Array(3) [3, 2, 1]
typedArray.toReversed()
typedArray を逆順に並べ替えてその結果の配列を返します。typedArray 自身は並べ替えられません。
const arr = new Int16Array([1, 2, 3]); console.log(arr.toReversed()) // => Int16Array(3) [3, 2, 1] console.log(arr); // => Int16Array(3) [1, 2, 3]
配列から文字列への変換
typedArray.toString()
配列を文字列に変換します。
const arr = new Int16Array([1, 2, 3]);
console.log(arr.toString()); // => "1,2,3,A,B,C"
typedArray.toLocaleString(locale, option)
配列要素をロケールに従った文字列に変換します。ロケールを locale
で指定することもできます。option
には単位や貨幣記号などの情報を渡すこともできます。
const arr = new Int16Array([9800, 16500]); console.log(arr.toLocaleString()); // => "9,800,16,500" console.log(arr.toLocaleString("ja")); // => "9,800,16,500" console.log(arr.toLocaleString("ja", { style: "currency", currency: "JPY"})); // => "¥9,800,¥16,500"
typedArray.join(separator)
typedArray の各要素の値を separator
で連結した文字列を返します。separator
を省略した場合はカンマ(,
)で連結します。
const arr = new Int16Array(["23", "86", "62"]); console.log(arr.join()); // => 23,86,62 console.log(arr.join(" ")); // => 23 86 62 console.log(arr.join("-")); // => 23-86-62
配列要素の変更
typedArray.set(array, offset)
0 から数えて offset
番目の要素以降を配列または型付き配列 array
の要素で上書きします。typedArray
自身が変更されます。offset
を省略した場合は 0 番目から上書きされます。
const arr = new Int16Array([0, 1, 2, 3, 4, 5, 6]);
arr.set([333, 444, 555], 3);
console.log(arr); // => Int16Array(7) [0, 1, 2, 333, 444, 555, 6]
0 から数えて start
番目から end - 1
番目の要素の値を value
に置換します。typedArray
自身を書き換えます。start
が省略された場合は 0番目から、end
が省略された場合は最後までを置換します。
const arr = new Int16Array([0, 1, 2, 3, 4, 5]);
arr.fill(999, 2, 4);
console.log(arr); // => Int16Array(6) [0, 1, 999, 999, 4, 5]
typedArray.fill(value, start, end)
0 から数えて start
番目から end - 1
番目の要素の値を value
に置換します。typedArray
自身を書き換えます。start
が省略された場合は 0番目から、end
が省略された場合は最後までを置換します。
const arr = new Int16Array([0, 1, 2, 3, 4, 5]);
arr.fill(999, 2, 4);
console.log(arr); // => Int16Array(6) [0, 1, 999, 999, 4, 5]
typedArray.with(index, value)
0 から数えて index
番目の要素を value
に置換したものを返します。typedArray
は変更されません。
const arr = new Int16Array([0, 1, 2, 3, 4, 5]); console.log(arr.with(3, 999)); // => Int16Array(6) [0, 1, 2, 999, 4, 5] console.log(arr); // => Int16Array(6) [0, 1, 2, 3, 4, 5]
typedArray.copyWithin(target, start, end)
start
番目から end - 1
番目の要素を、target
番目からの要素と置き換えます。typedArray
自体を書き換えます。start
が省略された場合は 0番目から、end
が省略された場合は最後までをコピーします。下記の例では 0 から数えて 8番目から 10 - 1 = 9
番目の要素を、2番目からの要素にコピーしています。
const arr = new Int16Array([0, 1, 2, 3, 4, 5, 6, 7, 888, 999]);
arr.copyWithin(2, 8, 10);
console.log(arr); // => [0, 1, 888, 999, 4, 5, 6, 7, 888, 999]
分割代入
型付き配列でも下記のような分割代入が可能です。
const arr = new Int16Array([1, 2, 3, 4, 5, 6]); [a, b] = arr; console.log(a); // => 1 console.log(b); // => 2
途中をスキップすることもできます。
[a, b, , c] = arr; console.log(a); // => 1 console.log(b); // => 2 console.log(c); // => 4
...
を用いて残りの要素を配列として受け取ることもできます。
[a, b, ...c] = arr; console.log(a); // => 1 console.log(b); // => 2 console.log(c); // => [3, 4, 5, 6]