I am writing a function to decode data from a run length encoded format like:
{ dataGroup: { count: [4, 4, 2, 1], dataOne: [1, 3, 2, 1], dataTwo: [7, -1, 9, 0], dataThree: [3, 8, 1, 2] } }
to
{ groupName: { dataOne: [1, 1, 1, 1, 3, 3, 3, 3, 2, 2, 1], dataTwo: [7, 7, 7, 7,-1,-1,-1,-1, 9, 9, 0], dataThree: [3, 3, 3, 3, 8, 8, 8, 8, 1, 1, 2] } }
I have written two solutions to date but feel like there may yet be a better way.
function decode(obj) { const arrayLengthN = (N, data=null) => [...Array(N)].map(_ => data); const [ group ] = Object.keys(obj); const { count, ...data } = obj[group]; const dataKeys = Object.keys(data); // method one // output object to be written upon iteration over count and data const output = {}; // populate output with empty arrays to push to dataKeys.map(key => output[key] = []); // do the decoding count .map((n, i) => { dataKeys .map(key => { output[key].push(...arrayLengthN(n, data[key][i])); }); }); // method two const otherMethod = { [group]: Object.assign( {}, ...dataKeys.map((key) => { return { [key] : count .map((n, i) => dataKeys .map(key => arrayLengthN(n, data[key][i])) ) .flat(2) }; }) )}; return {[group]: output} // or return otherMethod }
Is there anything wrong with the first method? It feels clunky to create an object, add empty arrays to it, and then mutate that object from within a .map call. That being said, to me it seems far more readable.
Any help or comments much appreciated.
Cheers,
P