如何在JavaScript中合并TypedArrays?

时间:2012-12-28 15:02:52

标签: javascript typed-arrays

我想合并多个arraybuffers来创建一个Blob。但是,如你所知,  TypedArray没有“推”或有用的方法......

E.g:

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

因此,我想获得[ 1, 2, 3, 4, 5, 6 ]

7 个答案:

答案 0 :(得分:56)

使用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);

答案 1 :(得分:6)

我总是使用这个功能:

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;
}

原始函数没有检查null或类型

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

    return c;
}

答案 2 :(得分:2)

如果我有多个类型数组

            arrays = [ typed_array1, typed_array2,..... typed_array100]

我希望将所有1到100个子数组合并为单个“结果” 此功能对我有用。

  single_array = concat(arrays)


function concat(arrays) {
  // sum of individual array lengths
  let totalLength = arrays.reduce((acc, value) => acc + value.length, 0);

  if (!arrays.length) return null;

   let result = new Uint8Array(totalLength);

      // for each array - copy it over result
      // next array is copied right after the previous one
      let length = 0;
      for(let array of arrays) {
            result.set(array, length);
            length += array.length;
      }

      return result;
   }

答案 3 :(得分:0)

作为一个单行代码,它将使用任意数量的数组(此处为myArrays)和混合类型,只要结果类型将它们全部都包含(此处为Int8Array):

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

答案 4 :(得分:0)

我喜欢@prinzhorn的答案,但是我想要一些更灵活,更紧凑的东西:

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 += tArr.byteLength
  })
  return ret
}

merge([a, b], Float32Array)

答案 5 :(得分:0)

用于客户端〜ok解决方案:

const a = new Int8Array( [ 1, 2, 3 ] )
const b = new Int8Array( [ 4, 5, 6 ] )
const c = Int8Array.from([...a, ...b])

答案 6 :(得分:-1)

对于喜欢一线客的人:

  const binaryData = [
    new Uint8Array([1, 2, 3]),
    new Int16Array([4, 5, 6]),
    new Int32Array([7, 8, 9])
  ];

  const mergedUint8Array = new Uint8Array(binaryData.map(typedArray => [...new Uint8Array(typedArray.buffer)]).flat());