Как сгладить зажатый массив
В ту минуту я обнаружил, что пытаюсь сгладить 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);
}, []);
}
но до сих пор нет радости, он продолжает возвращать массив как есть. Любой может указать мне в правильном направлении и объяснить, почему это?
-EDIT-
Итог: мне нужно, чтобы он возвращал регулярный объект Array, как начальный, который не был введен.
Ответы
Ответ 1
Если enc
является Array
of Uint8ClampedArray
s, этот однострочный оператор должен работать:
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
не работает с типизированными массивами.
Ответ 2
Сначала я бы вычислил общую длину, а затем использовал set
. Преимуществом set
является
Если исходный массив является типизированным массивом, два массива могут совместно использовать такой же базовый 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
));
Ответ 3
Проверка MDN, TypedArray
не разделяет довольно много обычных функций массива 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"
Ответ 4
Изменить, обновить
firefox, ночной теперь возвращает [[object Uint8ClampedArray],[object Uint8ClampedArray],[object Uint8ClampedArray]]
в FileReader()
result
, как указано @Oriol.
Подход с использованием spread element
, rest element
, for..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);