【问题标题】:Create ArrayBuffer from Array (holding integers) and back again从 Array(保存整数)创建 ArrayBuffer 并再次返回
【发布时间】:2016-03-09 11:00:10
【问题描述】:

看起来很简单,但我不知道如何将填充整数的Array 转换为ArrayBuffer,然后再转换回Array。有很多示例将字符串转换为 ArrayBuffer,例如 here
使用这些示例我创建了这个:

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

那么数组也需要再次转换回来。为此我使用:

var array = new Uint16Array(arrayBuffer);

此解决方案似乎可行,但没有更简单的方法吗?

更新

它也应该适用于如下数组:

var array = [3,7426,78921]

【问题讨论】:

  • 您使用的是unsigned short,而不是int。最好引用精确大小的类型(例如uint8_t)。

标签: javascript arrays arraybuffer


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

    任何类型数组的缓冲区都可以通过.buffer属性访问,如anyone can read on MDN

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

    选择正确的类型数组

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

    1:这是unrestricted double,貌似是64bit IEEE 754 number

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

    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 丢失,因为我无法为其计算必要的信息。地图可以用来计算可以容纳数字的最小类型数组:

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

    用作:

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

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

    【讨论】:

    • 任何类型的数组都有.buffer属性
    • 好的,我已经接受了你的回答,但是在测试时我发现它不适用于更大的整数......那该怎么做呢?
    • Float64Array 特别将包含任何没有错误的javascript数字。实际上,我已经想分享一个我创建的算法,该算法计算包含任何 int 所需的数组类型(以便您可以使用最小的必要值)。但你粗鲁的态度改变了我的想法。
    • A 添加了我正在谈论的信息,以及对其他用户的警告。我很抱歉——我的脾气和过去的糟糕经历让我变得更好了。
    • 漂亮的帽子@TomášZato,例如昨天我仍然在这个问题上再次获得赞成票,看来你的回答也得分很高。祝您假期愉快!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-06
    • 2021-12-17
    • 2011-11-15
    • 2012-02-24
    • 2016-06-14
    相关资源
    最近更新 更多