How can I merge TypedArrays in JavaScript?

后端 未结 7 453
说谎
说谎 2020-12-09 01:01

I\'d like to merge multiple arraybuffers to create a Blob. however, as you know, TypedArray dosen\'t have \"push\" or useful methods...

E.g.:

var a          


        
相关标签:
7条回答
  • 2020-12-09 01:26

    for client-side ~ok solution:

    const a = new Int8Array( [ 1, 2, 3 ] )
    const b = new Int8Array( [ 4, 5, 6 ] )
    const c = Int8Array.from([...a, ...b])
    
    0 讨论(0)
  • 2020-12-09 01:28

    I like @prinzhorn's answer but I wanted something a bit more flexible and compact:

    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)
    
    0 讨论(0)
  • 2020-12-09 01:32

    I always use this function:

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

    The original function without checking for null or types

    function mergeTypedArraysUnsafe(a, b) {
        var c = new a.constructor(a.length + b.length);
        c.set(a);
        c.set(b, a.length);
    
        return c;
    }
    
    0 讨论(0)
  • 2020-12-09 01:34

    if I have multiple typed arrays

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

    I want concat all 1 to 100 sub array into single 'result' this function works for me.

      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;
       }
    
    0 讨论(0)
  • 2020-12-09 01:38

    As a one-liner, which will take an arbitrary number of arrays (myArrays here) and of mixed types so long as the result type takes them all (Int8Array here):

    let combined = Int8Array.from(Array.prototype.concat(...myArrays.map(a => Array.from(a))));
    
    0 讨论(0)
  • 2020-12-09 01:42

    Use the set method. But note, that you now need twice the memory!

    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);
    
    0 讨论(0)
提交回复
热议问题