如何压扁夹紧的阵列

时间:2016-06-29 02:10:58

标签: javascript arrays multidimensional-array flatten

在那一刻我发现自己一直试图压扁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);
}, []);

与concat

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

并通过一个函数

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

但到目前为止还没有快乐,它会不断地返回阵列。任何人都可以指出我正确的方向并解释为什么会这样?

CNC中 底线:我需要它来返回一个常规的Array对象,就像未键入的起始对象一样。

4 个答案:

答案 0 :(得分:4)

我先计算总长度然后再使用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,proposed by 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)
);




答案 1 :(得分:3)

如果encArray的{​​{1}},则此单行语句应该有效:

Uint8ClampedArray

这相当于:

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]]不适用于Typed Arrays。

答案 2 :(得分:2)

检查MDN,TypedArray s不共享相当多的普通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"

答案 3 :(得分:1)

修改,更新

firefox,每晚都在[{1}} [[object Uint8ClampedArray],[object Uint8ClampedArray],[object Uint8ClampedArray]]返回FileReader(),如@Oriol所述。

使用resultspread elementrest element的方法,使用for..ofBlob()返回与铬,铬相同的结果; FileReader()TextEncoder(); TextDecoder()接近



JSON.parse()




或者,简而言之,正如@Oriol

所建议的那样
var enc = [new Uint8ClampedArray(900)
            , new Uint8ClampedArray(900)
           , new Uint8ClampedArray(900)];

var res = [];
for (let prop of enc) [...res] = [...res, ...prop];

console.log(res);

您可以使用var res = []; var enc = [new Uint8ClampedArray(900), new Uint8ClampedArray(900)]; for (let prop of enc) res.push(...prop); 将参数连接到单个Blob()对象,BlobFileReader()



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