Подтвердить что ты не робот

Как я могу объединить TypedArrays в JavaScript?

Я хотел бы объединить несколько массивных буферов для создания Blob. однако, как вы знаете,  TypedArray dosen't имеют "push" или полезные методы...

например:.

var a = new Int8Array( [ 1, 2, 3 ] );
var b = new Int8Array( [ 4, 5, 6 ] );

В результате я хотел бы получить [ 1, 2, 3, 4, 5, 6 ].

4b9b3361

Ответ 1

Используйте метод set. Но имейте в виду, что теперь вам нужно в два раза больше памяти!

var a = new Int8Array( [ 1, 2, 3 ] );
var b = new Int8Array( [ 4, 5, 6 ] );

var c = new Int8Array(a.length + b.length);
c.set(a);
c.set(b, a.length);

console.log(a);
console.log(b);
console.log(c);

Ответ 2

Я всегда использую эту функцию:

function mergeTypedArrays(a, b) {
    // Checks for truthy values on both arrays
    if(!a && !b) throw 'Please specify valid arguments for parameters a and b.';  

    // Checks for truthy values or empty arrays on each argument
    // to avoid the unnecessary construction of a new array and
    // the type comparison
    if(!b || b.length === 0) return a;
    if(!a || a.length === 0) return b;

    // Make sure that both typed arrays are of the same type
    if(Object.prototype.toString.call(a) !== Object.prototype.toString.call(b))
        throw 'The types of the two arguments passed for parameters a and b do not match.';

    var c = new a.constructor(a.length + b.length);
    c.set(a);
    c.set(b, a.length);

    return c;
}

Исходная функция без проверки на нуль или типы

function mergeTypedArraysUnsafe(a, b) {
    var c = new a.constructor(a.length + b.length);
    c.set(a);
    c.set(b, a.length);

    return c;
}

Ответ 3

В качестве однострочника, который будет принимать произвольное количество массивов (здесь myArrays) и смешанных типов, если только тип результата принимает их все (Int8Array здесь):

let combined = Int8Array.from(Array.prototype.concat(...myArrays.map(a => Array.from(a))));

Ответ 4

Мне нравится @prinzhorn answer, но я хотел что-то более гибкое и компактное:

var a = new Uint8Array( [ 1, 2, 3 ] );
var b = new Float32Array( [ 4.5, 5.5, 6.5 ] );

const merge = (tArrs, type = Uint8Array) => {
  const ret = new (type)(tArrs.reduce((acc, tArr) => acc + tArr.byteLength, 0))
  let off = 0
  tArrs.forEach((tArr, i) => {
    ret.set(tArr, off)
    off += tArrs[i].byteLength
  })
  return ret
}

merge([a, b], Float32Array)