如何展平夹紧的阵列
How to flatten a clamped array
此刻我发现自己卡住了试图压平 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);
}, []);
}
但到目前为止没有任何乐趣,它保持 return 数组原样。谁能给我指出正确的方向并解释为什么会这样?
-编辑-
底线:我需要它 return 一个常规的 Array 对象,比如未键入的起始对象。
查看 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"
如果 enc
是 Uint8ClampedArray
的 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]));
不幸的是 return [1, 2, 3, 4]
但 [Uint8ClampedArray[4]]
。 concat
不适用于类型化数组。
我会先计算总长度,然后再使用set
。 set
的优点是
If the source array is a typed array, the two arrays may share the
same underlying ArrayBuffer; the browser will intelligently copy the
source range of the buffer to the destination range.
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,如 。正确的方法是
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)
);
编辑、更新
firefox,目前 returns [[object Uint8ClampedArray],[object Uint8ClampedArray],[object Uint8ClampedArray]]
在 FileReader()
result
.
指出
一种使用 spread element
、rest element
、for..of
的方法,returns 与铬的结果相同,chrome 使用 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);
此刻我发现自己卡住了试图压平 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);
}, []);
}
但到目前为止没有任何乐趣,它保持 return 数组原样。谁能给我指出正确的方向并解释为什么会这样?
-编辑- 底线:我需要它 return 一个常规的 Array 对象,比如未键入的起始对象。
查看 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"
如果 enc
是 Uint8ClampedArray
的 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]));
不幸的是 return [1, 2, 3, 4]
但 [Uint8ClampedArray[4]]
。 concat
不适用于类型化数组。
我会先计算总长度,然后再使用set
。 set
的优点是
If the source array is a typed array, the two arrays may share the same underlying ArrayBuffer; the browser will intelligently copy the source range of the buffer to the destination range.
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,如
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)
);
编辑、更新
firefox,目前 returns [[object Uint8ClampedArray],[object Uint8ClampedArray],[object Uint8ClampedArray]]
在 FileReader()
result
一种使用 spread element
、rest element
、for..of
的方法,returns 与铬的结果相同,chrome 使用 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);