Javascript 从 Array(保存整数)创建 ArrayBuffer 并再次返回

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34089569/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 15:54:17  来源:igfitidea点击:

Create ArrayBuffer from Array (holding integers) and back again

javascriptarraysarraybuffer

提问by Wilt

It seems so simple, but I cannot find out how to convert an Arrayfilled with integers to an ArrayBufferand back again to an Array. There are lots of examples where strings are converted to an ArrayBufferlike for example here.
Using these examples I created this:

看起来很简单,但我不知道如何将Array填充的整数转换为 anArrayBuffer并再次转换为Array. 有很多字符串被转换为ArrayBuffer类似的例子,例如这里
使用这些示例我创建了这个:

/**
 * Convert string to array buffer.
 *
 * @param {Array.<int>} array
 * @returns {ArrayBuffer}
 */
self.arrayToArrayBuffer = function( array ) {
    var length = array.length;
    var buffer = new ArrayBuffer( length * 2 );
    var view = new Uint16Array(buffer);
    for ( var i = 0; i < length; i++) {
        view[i] = array[i];
    }
    return buffer;
}

Then the array also needs to converted back again. For this I use:

然后数组也需要再次转换回来。为此,我使用:

var array = new Uint16Array(arrayBuffer);

This solution seems to work, but is there no easier way to do this?

这个解决方案似乎有效,但没有更简单的方法来做到这一点吗?

UPDATE

更新

It should also work for an array like:

它也应该适用于像这样的数组:

var array = [3,7426,78921]

回答by Tomá? Zato - Reinstate Monica

Yes, there's a simple way without manually writing a loop (the loop still exists somewhere in background):

是的,有一种无需手动编写循环的简单方法(该循环仍然存在于后台某处):

new Uint16Array([1,2,3]);

That's all. Of course, floating numbers will be rounded down and big numbers will overflow.

就这样。当然,浮点数会四舍五入,大数会溢出。

Converting typed array to buffer

将类型化数组转换为缓冲区

The buffer of any typed array is accessible through .bufferproperty, as anyonecan read on MDN:

任何类型数组的缓冲区都可以通过.buffer属性访问,因为任何人都可以在 MDN 上阅读

new Uint16Array([1,2,3]).buffer;

Chosing the right typed array

选择正确的类型化数组

Be warned that mentioned Uint16Arraywill only hold integers (no floating point) between zero and 65535. To hold any javascript Number1you will want to use Float64Array- the bigest one, taking 8 bytes total.

请注意,提到的Uint16Array将只保存 0 到 65535 之间的整数(无浮点数)。要保存您将要使用的任何 javascript 数字1Float64Array- 最大的一个,总共需要 8 个字节。

1:Which is unrestricted double, which appears to be 64bit IEEE 754 number

1:这是不受限制的双精度数,似乎是 64 位IEEE 754 数字

Here's a map I have created that maps some of the important information related to number data types:

这是我创建的映射,它映射了与数字数据类型相关的一些重要信息:

var NUMBER_TYPE = [
  {name: "uint8",   bytes:1, max:        255,       min: 0,                floating: false, array: Uint8Array},
  {name: "int8",    bytes:1, max:        127,       min: -128,             floating: false, array: Int8Array},
  {name: "uint16",  bytes:2, max:      65535,       min: 0,                floating: false, array: Uint16Array},
  {name: "int16",   bytes:2, max:      32767,       min: -32768,           floating: false, array: Int16Array},
  {name: "uint32",  bytes:4, max: 4294967295,       min: 0,                floating: false, array: Uint32Array},
  {name: "int32",   bytes:4, max: 2147483647,       min: -2147483648,      floating: false, array: Int32Array},
  {name: "float64", bytes:8, max: Number.MAX_VALUE, min: Number.MIN_VALUE, floating: true , array: Float64Array}
];

Float 32 is missing as I was unable to calculate necessary information for it. The map, as it is, can be used to calculate the smallest typed array you can fit a Number in:

Float 32 丢失了,因为我无法为其计算必要的信息。该映射,就其本身而言,可用于计算您可以将 Number 放入的最小类型化数组:

function findNumberType(num) {
    // detect whether number has something after the floating point
    var float = num!==(num|0);
    // Prepare the return variable
    var type = null;
    for(var i=0,l=NUMBER_TYPE.length; i<l; i++) {
      // Assume this type by default - unless break is hit, every type ends as `float64`
      type = NUMBER_TYPE[i];
      // Comparison asserts that number is in bounds and disalows floats to be stored 
      // as integers
      if( (!float || type.floating) && num<=type.max && num>=type.min) {
          // If this breaks, the smallest data type has been chosen
          break;
      }
    }
    return type;
}

Used as:

用作:

var n = 1222;
var buffer = new (findNumberType(n).array)([n]);

Note that this only works if NUMBER_TYPEis properly ordered.

请注意,这仅在NUMBER_TYPE正确订购时才有效。

回答by Martin Wantke

You can't use an ArrayBuffer directly, but you can create a typed array from a normal array by using the frommethod:

您不能直接使用 ArrayBuffer,但可以使用from方法从普通数组创建类型化数组:

let typedArray = Int32Array.from([-2, -1, 0, 1, 2])