31

私はArrayBufferオブジェクトを扱っており、それらを複製したいと考えています。これは実際のポインターと を使用するとかなり簡単memcpyですが、Javascript で簡単に実行する方法が見つかりませんでした。

今、これが私のコピー方法ですArrayBuffers

function copy(buffer)
{
    var bytes = new Uint8Array(buffer);
    var output = new ArrayBuffer(buffer.byteLength);
    var outputBytes = new Uint8Array(output);
    for (var i = 0; i < bytes.length; i++)
        outputBytes[i] = bytes[i];
    return output;
}

もっときれいな方法はありますか?

4

8 に答える 8

52

私は次の方法を好みます

function copy(src)  {
    var dst = new ArrayBuffer(src.byteLength);
    new Uint8Array(dst).set(new Uint8Array(src));
    return dst;
}
于 2014-03-01T12:57:49.943 に答える
33

ソースデータビューを渡すだけでコピーが実行されるようです。

var a = new Uint8Array([2,3,4,5]);
var b = new Uint8Array(a);
a[0] = 6;
console.log(a); // [6, 3, 4, 5]
console.log(b); // [2, 3, 4, 5]

FF 33 と Chrome 36 でテスト済み。

于 2014-08-12T03:35:24.443 に答える
32

ArrayBufferslice(http://www.khronos.org/registry/typedarray/specs/latest/)をサポートすることになっているので、試してみることができます、

buffer.slice(0);

これはChrome18では機能しますが、Firefox 10または11では機能しません。Firefoxについては、手動でコピーする必要があります。slice()Chromeslice()は手動コピーよりもパフォーマンスが優れているため、Firefoxでモンキーパッチを適用できます。これは次のようになります、

if (!ArrayBuffer.prototype.slice)
    ArrayBuffer.prototype.slice = function (start, end) {
        var that = new Uint8Array(this);
        if (end == undefined) end = that.length;
        var result = new ArrayBuffer(end - start);
        var resultArray = new Uint8Array(result);
        for (var i = 0; i < resultArray.length; i++)
           resultArray[i] = that[i + start];
        return result;
    }

その後、あなたは呼び出すことができます、

buffer.slice(0);

ChromeとFirefoxの両方でアレイをコピーします。

于 2012-04-11T06:49:27.843 に答える
2

チャックジの答えのより高速で少し複雑なバージョン。大規模な型付き配列では、コピー操作を最大 8 分の 1 に削減する必要があります。基本的に、8 バイトのチャンクをできるだけ多くコピーしてから、残りの 0 ~ 7 バイトをコピーします。これは、現在のバージョンの IE で特に役立ちます。これは、ArrayBuffer にスライス メソッドが実装されていないためです。

if (!ArrayBuffer.prototype.slice)
    ArrayBuffer.prototype.slice = function (start, end) {
    if (end == undefined) end = that.length;
    var length = end - start;
    var lengthDouble = Math.floor(length / Float64Array.BYTES_PER_ELEMENT); 
    // ArrayBuffer that will be returned
    var result = new ArrayBuffer(length);

    var that = new Float64Array(this, start, lengthDouble)
    var resultArray = new Float64Array(result, 0, lengthDouble);

    for (var i = 0; i < resultArray.length; i++)
       resultArray[i] = that[i];

    // copying over the remaining bytes
    that = new Uint8Array(this, start + lengthDouble * Float64Array.BYTES_PER_ELEMENT)
    resultArray = new Uint8Array(result, lengthDouble * Float64Array.BYTES_PER_ELEMENT);

    for (var i = 0; i < resultArray.length; i++)
       resultArray[i] = that[i];

    return result;
}
于 2014-01-30T20:03:40.370 に答える