Javascript Gecko 2中的类型化数组:float32数组连接和扩展

Javascript Gecko 2中的类型化数组:float32数组连接和扩展,javascript,arrays,gecko,typed-arrays,Javascript,Arrays,Gecko,Typed Arrays,我有点困惑 我有几个float数组,它们没有concat方法。顺便说一句,我不知道他们提前了多少人。 我希望将它们全部连接到另一个Float32Array中,但是: 正如我之前所说,没有连接方法 如果我试图写入超过数组长度的内容,则数组不会展开(也就是说,这不起作用-请注意event.frameBuffer和buffer都是Float32Array,我不知道缓冲区的最终长度是多少): var length\u现在=buffer.length; 对于(变量i=0;i

我有点困惑

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

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

var length\u现在=buffer.length;
对于(变量i=0;i
我找到的唯一解决方案是在常规数组中复制Float32Array,这绝对不是我想要的。stackoverflowers,您会怎么做?

类型化数组基于,无法动态调整大小,因此无法写入数组末尾或使用
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);

或者,如果您尝试加入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;
}
//一个用于对数组中的值求和的行程序
函数和(a){
返回a.reduce(函数(a,b){returna+b;},0);
}
//使用Uint8Array对象数组调用此函数
函数bufjoin(bufs){
var lens=bufs.map(函数(a){返回a.length;});
var aout=新的UINT8阵列(总和(镜头));

对于(var i=0;i我有相同的问题,您可以将以下内容添加到原型中

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

这真是太棒了。有两个问题:继续重新创建一个新的类型化数组不会影响性能?你在哪里找到关于.set函数成员的文档?它不在你链接的页面中。@janesconference,嗯,它不一定会影响性能,因为
set()
可能是以本机方式实现的,因此,内存块的速度非常快,但它会影响内存,因为您不能仅扩展现有的类型数组。根据数组大小,如果内存不足,可能会发生抖动,性能会因此大大降低。@FrédéricHamidi:还有一个问题不是“本机”的问题实现:假设您有n个数组,其中有m个元素要连接。您的复杂性是O(m^2),因为您将复制越来越大的数据块。最佳解决方案是摊销O(m)。
var array1 = new Float32Array(10000000),
    array2 = new Float32Array(10000000);

var array3 = array1.concat(array2);