14

我对Javascript Typed Arrays有点困惑。

我有几个Float32Array,它们没有concat方法。我不知道他们提前多少,顺便说一句。我想将它们全部连接到另一个 Float32Array 中,但是:

  • 正如我之前所说,没有连接方法
  • 如果我尝试写入超过数组长度,则数组不会扩展(也就是说这不起作用 - 请注意 event.frameBuffer 和 buffer 都是 Float32Array 并且我不知道我的缓冲区的最终长度是多少):

var length_now = buffer.length;
for (var i = 0; i < event.frameBuffer.length; i += 1) {
      buffer [length_now + i] = event.frameBuffer[i];
}

我找到的唯一解决方案是将 Float32Array 复制到常规数组中,这绝对不是我想要的。你会怎么做,stackoverflowers?

4

3 回答 3

24

Typed arrays are based on array buffers, which cannot be resized dynamically, so writing past the end of the array or using push() is not possible.

One way to achieve what you want would be to allocate a new Float32Array, large enough to contain both arrays, and perform an optimized copy:

function Float32Concat(first, second)
{
    var firstLength = first.length,
        result = new Float32Array(firstLength + second.length);

    result.set(first);
    result.set(second, firstLength);

    return result;
}

That would allow you to write:

buffer = Float32Concat(buffer, event.frameBuffer);
于 2010-12-29T13:18:21.230 回答
3

或者,如果您尝试加入 N 个数组:

// one-liner to sum the values in an array
function sum(a){
  return a.reduce(function(a,b){return a+b;},0);
}

// call this with an array of Uint8Array objects
function bufjoin(bufs){
  var lens=bufs.map(function(a){return a.length;});
  var aout=new Uint8Array(sum(lens));
  for (var i=0;i<bufs.length;++i){
    var start=sum(lens.slice(0,i));
    aout.set(bufs[i],start); // copy bufs[i] to aout at start position
  }
  return aout;
}
于 2012-12-30T08:53:07.023 回答
2

我有同样的问题,您可以将以下内容添加到原型中

Float32Array.prototype.concat = function() {
    var bytesPerIndex = 4,
        buffers = Array.prototype.slice.call(arguments);

    // add self
    buffers.unshift(this);

    buffers = buffers.map(function (item) {
        if (item instanceof Float32Array) {
            return item.buffer;
        } else if (item instanceof ArrayBuffer) {
            if (item.byteLength / bytesPerIndex % 1 !== 0) {
                throw new Error('One of the ArrayBuffers is not from a Float32Array');  
            }
            return item;
        } else {
            throw new Error('You can only concat Float32Array, or ArrayBuffers');
        }
    });

    var concatenatedByteLength = buffers
        .map(function (a) {return a.byteLength;})
        .reduce(function (a,b) {return a + b;}, 0);

    var concatenatedArray = new Float32Array(concatenatedByteLength / bytesPerIndex);

    var offset = 0;
    buffers.forEach(function (buffer, index) {
        concatenatedArray.set(new Float32Array(buffer), offset);
        offset += buffer.byteLength / bytesPerIndex;
    });

    return concatenatedArray;
};

现在你可以简单地做

var array1 = new Float32Array(10000000),
    array2 = new Float32Array(10000000);

var array3 = array1.concat(array2);
于 2016-07-14T01:35:04.910 回答