Gecko 2中的Typed Arrays:Float32Array连接和扩展

时间:2010-12-29 12:52:08

标签: javascript arrays gecko typed-arrays

我对Javascript Typed Arrays感到困惑。

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

  • 正如我之前所说,没有连接方法
  • 如果我尝试写过数组长度,数组不会扩展(也就是说这不起作用 - 请注意event.frameBuffer和缓冲区都是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?

3 个答案:

答案 0 :(得分:19)

类型化数组基于array buffers,无法动态调整大小,因此无法写入数组末尾或使用push()

实现目标的一种方法是分配一个新的Float32Array,大到足以包含两个数组,并执行优化副本:

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

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

    return result;
}

这将允许你写:

buffer = Float32Concat(buffer, event.frameBuffer);

答案 1 :(得分:2)

或者如果您正在尝试加入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;
}

答案 2 :(得分:1)

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

padding

现在你可以简单地做

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