2016-06-29 4 views
10

В тот момент, когда я нахожусь в попытке сгладить 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, как начальный, не набранный.

ответ

3

Если enc является Array из 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]]. concat не работает с типизированными массивами.

+0

Но это преобразует типизированные массивы в обычный массив (прежде чем преобразовывать его обратно в типизированный массив). Тогда в чем смысл использования типизированных массивов? – Oriol

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" 
+0

Это похоже на работу, хотя это было немного запутанным, как к тому, что 'a' является должно быть. Если он заменен на 'enc', он работает. – Xufox

+0

Я забыл скопировать мой тестовый массив, который назывался 'a'; – kazenorin

+0

Но это преобразует типизированные массивы в обычный массив (прежде чем преобразовывать его обратно в типизированный массив). Тогда в чем смысл использования типизированных массивов? – Oriol

4

Сначала я бы вычислил общую длину, а затем использовал 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 
 
));

Альтернативным использует капли, так как 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

Редактировать, Обновлено

светлячок, ночью в настоящее время возвращает [[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);

или покороче, как это было предложено @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);

+0

Да, это решение, которое я легко понимаю, потому что раньше я работал с Blobs. – iomv

+2

[Это не работает в Firefox] (http://i.stack.imgur.com/rQZGc.png). 'JSON.parse: неожиданный символ' – Oriol

+0

@Oriol Можете ли вы описать« не работает »? 'JSON.parse: неожиданный символ' Не получил ошибку, здесь, при любом подходе. Можете ли вы создать jsfiddle или plnkr для демонстрации? Вы также можете использовать '.split (/, /). Map (Number)'. Что такое неожиданный персонаж? – guest271314

Смежные вопросы