{"ScriptPreparationCode":"var nrows = 500000,\r\n nyears = [...Array(20).keys()].map(x =\u003E 2000 \u002B x),\r\n nages = [...Array(20).keys()].map(x =\u003E \u0060${18\u002Bx}\u0060),\r\n npeople = [...Array(nrows / nyears.length / nages.length | 0).keys()].map(x =\u003E \u0060Person${x}\u0060);\r\n\r\nvar getOneRotate = (x, i) =\u003E x[(i / x.length | 0) % x.length];\r\n\r\nvar data = Array(nrows).fill(0).map((x, i) =\u003E ({\r\n year: getOneRotate(nyears,i),\r\n name: getOneRotate(npeople,i),\r\n age: getOneRotate(nages,i),\r\n value: (i / nyears.length | 0) % nyears.length\r\n}));\r\n\r\nconst NA=\u0027NA\u0027;\r\n\r\nfunction forloopObjectAssign(x) {\r\n let lname, lage, res=[], years = {};\r\nfor ( var i = 0 ; i \u003C x.length ; i\u002B\u002B ) {\r\n const {year, value, name, age} = x[i];\r\n if ( lname != name || lage != age ) \r\n res.push({name, age});\r\n res[ res.length-1 ][year] = value;\r\n \r\n years[year] = NA;\r\n lname = name;\r\n lage = age;\r\n}\r\nreturn res.map( x =\u003E Object.assign({...years}, x) );\r\n}\r\n\r\nfunction forloopEntries(x) {\r\nlet lname, lage, res=[], years = {};\r\nfor ( var i = 0 ; i \u003C x.length ; i\u002B\u002B ) {\r\n const {year, value, name, age} = x[i];\r\n if ( lname != name|| lage != age ) \r\n res.push([[\u0027name\u0027,name],[\u0027age\u0027,age]]);\r\n res[ res.length-1 ].push([year,value]);\r\n \r\n years[year] = NA;\r\n lname = name;\r\n lage = age;\r\n}\r\n\r\nreturn res.map( x =\u003E Object.fromEntries(Object.entries(years).concat(x)) );\r\n}\r\n\r\nfunction mapReduceSet(data) {\r\n years = new Set;\r\n result = Object\r\n .values(data.reduce((r, { name, year, value, ...o }) =\u003E {\r\n r[name] = r[name] || { name, ...o };\r\n r[name][year] = value;\r\n years.add(year);\r\n return r;\r\n }, {}))\r\n .map(\r\n (y =\u003E o =\u003E ({ ...y, ...o }))\r\n (Object.fromEntries([...years].map(y =\u003E [y, NaN])))\r\n );\r\n return result;\r\n}\r\n\r\nlet yearsGenerator = {}\r\nfunction* groupByName(entries) {\r\n let group = null;\r\n\r\n for (const {name, year, value, age} of entries) {\r\n if (group === null || group.name !== name || group.age !== age) {\r\n if (group !== null) {\r\n yield group;\r\n }\r\n \r\n group = {name, age};\r\n }\r\n\r\n group[year] = value;\r\n yearsGenerator[year] = \u0027NA\u0027;\r\n }\r\n\r\n if (group !== null) {\r\n yield group;\r\n }\r\n}\r\n\r\nfunction generator(entries) { return [...groupByName(entries)].map(x=\u003EObject.assign({...yearsGenerator},x)) }","TestCases":[{"Name":"generator","Code":"generator(data)","IsDeferred":false},{"Name":"forloop object assign","Code":"forloopObjectAssign(data)","IsDeferred":false},{"Name":"mapReduceSet","Code":"mapReduceSet(data)","IsDeferred":false},{"Name":"forloopEntries","Code":"forloopEntries(data)","IsDeferred":false}]}