如何压平夹紧的数组



此刻,我发现自己在试图压平Uint8ClampedArray时陷入了困境。

起始数组结构是data = [227, 138, 255…],在从类似的enc = [Uint8ClampedArray[900], Uint8ClampedArray[900], Uint8ClampedArray[900]...]创建数组后,我尝试将其压平

我尝试了很多方法/解决方案,但似乎没有一个有效:

MDN建议的方法

var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {
  return a.concat(b);
}, []);

带凹面

data = [].concat.apply([], enc);

并通过功能

function flatten(arr) {
  return arr.reduce(function (flat, toFlatten) {
    return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
  }, []);
}

但到目前为止没有任何乐趣,它一直按原样返回阵列。任何人都可以为我指明正确的方向,并解释为什么会这样?

-编辑-一句话:我需要它返回一个常规的Array对象,就像未键入的起始对象一样。

如果encUint8ClampedArray s的Array,则此一行语句应该有效:

var flattened = Uint8ClampedArray.from(enc.reduce((a, b) => [...a, ...b], []));

这相当于:

var flattened = Uint8ClampedArray.from(enc.reduce(function(a, b){
  return Array.from(a).concat(Array.from(b));
}, []));

为了回答您关于reduce为什么不适合您的实际问题:

[].concat(Uint8ClampedArray([1, 2, 3, 4]));

不幸的是没有返回[1, 2, 3, 4]而是返回[Uint8ClampedArray[4]]concat不适用于类型化阵列。

我会先计算总长度,然后使用setset的优点是

如果源数组是类型化数组,则这两个数组可以共享相同的底层ArrayBuffer;浏览器将智能地复制缓冲区的源范围到目标范围。

function flatten(arrays, TypedArray) {
  var arr = new TypedArray(arrays.reduce((n, a) => n + a.length, 0));
  var i = 0;
  arrays.forEach(a => { arr.set(a,i); i += a.length; });
  return arr;
}
console.log(flatten(
  [new Uint8ClampedArray([1,2,3]), new Uint8ClampedArray([4,5,6])],
  Uint8ClampedArray
));

另一种选择是使用blob,正如guest271314所建议的那样。正确的方法是

function flatten(arrays, TypedArray, callback) {
  var reader = new FileReader();
  reader.onload = () => {
    callback(new TypedArray(reader.result));
  };
  reader.readAsArrayBuffer(new Blob(arrays));
}
flatten(
  [new Uint8ClampedArray([1,2,3]), new Uint8ClampedArray([4,5,6])],
  Uint8ClampedArray,
  result => console.log(result)
);

检查MDN,TypedArrays没有共享很多正常的JS数组函数。

您可以从钳制数组中收集值,然后初始化一个新的数组,如下所示:

var enc = [Uint8ClampedArray.of(1, 2), Uint8ClampedArray.of(4, 8), Uint8ClampedArray.of(16, 32)]
var flattened = Uint8ClampedArray.from(enc.reduce(function(acc, uintc){
  Array.prototype.push.apply(acc, uintc)
  return acc;
}, []));
console.log(flattened); // [object Uint8ClampedArray]
console.log(flattened.join(',')); // "1,2,4,8,16,32"

编辑、更新

firefox,night目前在FileReader()result返回[[object Uint8ClampedArray],[object Uint8ClampedArray],[object Uint8ClampedArray]],正如@Oriol所指出的。

一种使用spread elementrest elementfor..of的方法,其返回与铬相同的结果,铬使用Blob()FileReader()TextEncoder()TextDecoder()JSON.parse()接近

var enc = [new Uint8ClampedArray(900)
            , new Uint8ClampedArray(900)
           , new Uint8ClampedArray(900)];
var res = [];
for (let prop of enc) [...res] = [...res, ...prop];
console.log(res);

或者,更简短地说,正如@Oriol 所建议的那样

var res = [];
var enc = [new Uint8ClampedArray(900), new Uint8ClampedArray(900)]; 
for (let prop of enc) res.push(...prop);

您可以使用Blob(),它将参数连接到单个Blob对象、FileReader()JSON.parse()

var enc = [new Uint8ClampedArray(900)
            , new Uint8ClampedArray(900)
           , new Uint8ClampedArray(900)];
var blob = new Blob([enc]);
var reader = new FileReader();
reader.onload = () => {
  console.log(JSON.parse("[" + reader.result + "]"))
}
reader.readAsText(blob);

或者,使用TextEncoder()TextDecoder()JSON.parse()

var enc = [new Uint8ClampedArray(900)
            , new Uint8ClampedArray(900)
           , new Uint8ClampedArray(900)];
var encoder = new TextEncoder();
var arr = encoder.encode(enc);
var decoder = new TextDecoder();
var res = JSON.parse("[" + decoder.decode(arr) + "]");
console.log(res);

相关内容

  • 没有找到相关文章

最新更新