Build an array of objects from some arrays





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







5















I have the following arrays:



const countries = ['Belgium', 'Uk']
const years = ['2019', '2018', '2017']
const colors = ['red', 'orange', 'green']


I want an array like that:



const result = [
{
country: 'Belgium',
year: '2019',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Belgium',
year: '2018',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Belgium',
year: '2017',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Uk',
year: '2019',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Uk',
year: '2018',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Uk',
year: '2017',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Tot',
year: '2019',
red: // sum of the values of the red key for each country in the year 2019,
orange: // sum of the values of the orange key for each country in the year 2019,
green: // sum of the values of the green key for each country in the year 2019,
},
{
country: 'Tot',
year: '2018',
red: // sum of the values of the red key for each country in the year 2018,
orange: // sum of the values of the orange key for each country in the year 2018,
green: // sum of the values of the green key for each country in the year 2018,
},
{
country: 'Tot',
year: '2017',
red: // sum of the values of the red key for each country in the year 2017,
orange: // sum of the values of the orange key for each country in the year 2017,
green: // sum of the values of the green key for each country in the year 2017,
},
]


So, for each year, and for each country, there must be an object containing the keys of each color. The value must be random.



Then, should be other objects with country = Total and with values of colors key the sum of the values of other objects.



This is what I'm trying to do:



function createValues() {
const min = 0
const max = 300
const dataset: any =
countries.forEach(country => {years.forEach(year => {colors.forEach(color => {dataset.push({country: country, year: year, [color]: random(min, max),})})})})}


But it doesn't work and I don't know how to compute the sum values.










share|improve this question

























  • I recommend making a seperate color object inside each country which contains the seperate colors.

    – Tvde1
    Jan 31 at 13:19


















5















I have the following arrays:



const countries = ['Belgium', 'Uk']
const years = ['2019', '2018', '2017']
const colors = ['red', 'orange', 'green']


I want an array like that:



const result = [
{
country: 'Belgium',
year: '2019',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Belgium',
year: '2018',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Belgium',
year: '2017',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Uk',
year: '2019',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Uk',
year: '2018',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Uk',
year: '2017',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Tot',
year: '2019',
red: // sum of the values of the red key for each country in the year 2019,
orange: // sum of the values of the orange key for each country in the year 2019,
green: // sum of the values of the green key for each country in the year 2019,
},
{
country: 'Tot',
year: '2018',
red: // sum of the values of the red key for each country in the year 2018,
orange: // sum of the values of the orange key for each country in the year 2018,
green: // sum of the values of the green key for each country in the year 2018,
},
{
country: 'Tot',
year: '2017',
red: // sum of the values of the red key for each country in the year 2017,
orange: // sum of the values of the orange key for each country in the year 2017,
green: // sum of the values of the green key for each country in the year 2017,
},
]


So, for each year, and for each country, there must be an object containing the keys of each color. The value must be random.



Then, should be other objects with country = Total and with values of colors key the sum of the values of other objects.



This is what I'm trying to do:



function createValues() {
const min = 0
const max = 300
const dataset: any =
countries.forEach(country => {years.forEach(year => {colors.forEach(color => {dataset.push({country: country, year: year, [color]: random(min, max),})})})})}


But it doesn't work and I don't know how to compute the sum values.










share|improve this question

























  • I recommend making a seperate color object inside each country which contains the seperate colors.

    – Tvde1
    Jan 31 at 13:19














5












5








5








I have the following arrays:



const countries = ['Belgium', 'Uk']
const years = ['2019', '2018', '2017']
const colors = ['red', 'orange', 'green']


I want an array like that:



const result = [
{
country: 'Belgium',
year: '2019',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Belgium',
year: '2018',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Belgium',
year: '2017',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Uk',
year: '2019',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Uk',
year: '2018',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Uk',
year: '2017',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Tot',
year: '2019',
red: // sum of the values of the red key for each country in the year 2019,
orange: // sum of the values of the orange key for each country in the year 2019,
green: // sum of the values of the green key for each country in the year 2019,
},
{
country: 'Tot',
year: '2018',
red: // sum of the values of the red key for each country in the year 2018,
orange: // sum of the values of the orange key for each country in the year 2018,
green: // sum of the values of the green key for each country in the year 2018,
},
{
country: 'Tot',
year: '2017',
red: // sum of the values of the red key for each country in the year 2017,
orange: // sum of the values of the orange key for each country in the year 2017,
green: // sum of the values of the green key for each country in the year 2017,
},
]


So, for each year, and for each country, there must be an object containing the keys of each color. The value must be random.



Then, should be other objects with country = Total and with values of colors key the sum of the values of other objects.



This is what I'm trying to do:



function createValues() {
const min = 0
const max = 300
const dataset: any =
countries.forEach(country => {years.forEach(year => {colors.forEach(color => {dataset.push({country: country, year: year, [color]: random(min, max),})})})})}


But it doesn't work and I don't know how to compute the sum values.










share|improve this question
















I have the following arrays:



const countries = ['Belgium', 'Uk']
const years = ['2019', '2018', '2017']
const colors = ['red', 'orange', 'green']


I want an array like that:



const result = [
{
country: 'Belgium',
year: '2019',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Belgium',
year: '2018',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Belgium',
year: '2017',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Uk',
year: '2019',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Uk',
year: '2018',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Uk',
year: '2017',
red: random(min, max),
orange: random(min, max),
green: random(min, max),
},
{
country: 'Tot',
year: '2019',
red: // sum of the values of the red key for each country in the year 2019,
orange: // sum of the values of the orange key for each country in the year 2019,
green: // sum of the values of the green key for each country in the year 2019,
},
{
country: 'Tot',
year: '2018',
red: // sum of the values of the red key for each country in the year 2018,
orange: // sum of the values of the orange key for each country in the year 2018,
green: // sum of the values of the green key for each country in the year 2018,
},
{
country: 'Tot',
year: '2017',
red: // sum of the values of the red key for each country in the year 2017,
orange: // sum of the values of the orange key for each country in the year 2017,
green: // sum of the values of the green key for each country in the year 2017,
},
]


So, for each year, and for each country, there must be an object containing the keys of each color. The value must be random.



Then, should be other objects with country = Total and with values of colors key the sum of the values of other objects.



This is what I'm trying to do:



function createValues() {
const min = 0
const max = 300
const dataset: any =
countries.forEach(country => {years.forEach(year => {colors.forEach(color => {dataset.push({country: country, year: year, [color]: random(min, max),})})})})}


But it doesn't work and I don't know how to compute the sum values.







javascript arrays object






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 31 at 12:52









double-beep

3,10641432




3,10641432










asked Jan 31 at 10:10









bethbeth

214516




214516













  • I recommend making a seperate color object inside each country which contains the seperate colors.

    – Tvde1
    Jan 31 at 13:19



















  • I recommend making a seperate color object inside each country which contains the seperate colors.

    – Tvde1
    Jan 31 at 13:19

















I recommend making a seperate color object inside each country which contains the seperate colors.

– Tvde1
Jan 31 at 13:19





I recommend making a seperate color object inside each country which contains the seperate colors.

– Tvde1
Jan 31 at 13:19












7 Answers
7






active

oldest

votes


















2














My solution






const countries = ['Belgium', 'Uk'];
const years = ['2019', '2018', '2017'];
const colors = ['red', 'orange', 'green'];

const min = 0;
const max = 300;

console.log(getTotal(
getResult(countries, years, colors),
colors
));

function getResult(countries, years, colors) {
const result = ;
countries.forEach(country => {
years.forEach(year => {
const item = {
country: country,
year: year
};
colors.forEach(color => {
item[color] = random(min, max);
});
result.push(item);
});
});
return result;
}

function getTotal(data, colors) {
const total = {};
data.forEach(item => {
if (typeof total[item.year] === 'undefined') {
total[item.year] = {};
colors.forEach(color => {
total[item.year][color] = item[color];
});
} else {
colors.forEach(color => {
total[item.year][color] += item[color];
});
}
});
for (var totalItem in total) {
data.push({country: 'Tot', year: totalItem, ...total[totalItem]});
}
return data;
}

function random(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}








share|improve this answer

































    4














    You could get a cartesian result of countries and years, get all totals and build the missing total objects.






    function getCartesian(object) {
    return Object.entries(object).reduce((r, [k, v]) => {
    var temp = ;
    r.forEach(s =>
    (Array.isArray(v) ? v : [v]).forEach(w =>
    (w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
    temp.push(Object.assign({}, s, { [k]: x }))
    )
    )
    );
    return temp;
    }, [{}]);
    }

    function random(min, max) {
    return Math.floor(Math.random() * (max - min)) + min;
    }

    const
    countries = ['Belgium', 'Uk'],
    years = ['2019', '2018', '2017'],
    colors = ['red', 'orange', 'green'],
    result = getCartesian({ country: countries, year: years })
    .map(o => Object.assign(o, ...colors.map(k => ({ [k]: random(0, 300) })))),
    totals = result.reduce((r, o) => (colors.forEach(color => {
    r[o.year] = r[o.year] || {};
    r[o.year][color] = (r[o.year][color] || 0) + o[color];
    }), r), {});

    result.push(...years.map(year => Object.assign(
    { country: 'TOT', year },
    ...colors.map(color => ({ [color]: totals[year][color] }))
    )));

    console.log(result);

    .as-console-wrapper { max-height: 100% !important; top: 0; }








    share|improve this answer


























    • That fancy name cartesian though.. nice"

      – Alvin Theodora
      Jan 31 at 10:41



















    3














    You could do something like this using forEach and reduce




    • Get all the possible combination of countries and years in combo


    • reduce the combo and get the sum for each color grouped based on the year


    • concat the combo array and total values grouped from the reduce





    const countries = ['Belgium', 'Uk']
    const years = ['2019', '2018', '2017']
    const colors = ['red', 'orange', 'green']

    function random(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    const combo = ;

    countries.forEach(country => {
    years.forEach(year => {

    const obj = {country,year};
    colors.forEach(color => {
    obj[color] = random(1, 10)
    })

    combo.push(obj)
    })
    })

    const total = combo.reduce((acc, {year, country,...rest}) => {
    acc[year] = acc[year] || {year,country: 'Tot'};

    for (let color in rest) {
    acc[year][color] = (acc[year][color] + rest[color]) || rest[color]
    }

    return acc;
    }, {})


    const final = combo.concat(Object.values(total))

    console.log(final)








    share|improve this answer





















    • 2





      elegant use spread operator, destructor and OR. Save in their recipes. Thanks.

      – eustatos
      Jan 31 at 10:47



















    1














    Double reduce and spread operator.



    For each country and then for each years, we are creating a new json. This json is made of the country + year key and colors we have to loop on aswell. Then we add the total.






    function random(min, max) {
    return Math.floor(Math.random() * (max - min)) + min;
    }

    const countries = ['Belgium', 'Uk'];
    const years = ['2019', '2018', '2017'];
    const colors = ['red', 'orange', 'green'];

    const arr = countries.reduce((tmp, x) => [
    ...tmp,

    ...years.map(y => colors.reduce((json, z) => {
    json[z] = random(0, 255);

    return json;
    }, {
    country: x,
    year: y,
    })),
    ], );

    // add the Tot
    const arrWithTotal = [
    ...arr,

    ...years.map(y => colors.reduce((json, x) => {
    json[x] = arr.reduce((tmp, z) => z.year === y ? tmp + z[x] : tmp, 0);

    return json;
    }, {
    country: 'Tot',
    year: y,
    })),
    ];

    console.log(arrWithTotal);








    share|improve this answer

































      1














      Here's a purely functional solution. It uses local mutation in Array#reduce, but the computation itself is pure:






      const ap = fs => xs => xs.flatMap (x => fs.map (f => f (x)))
      const lift2 = f => xs => ys => ap (xs.map (f)) (ys)

      // source: https://stackoverflow.com/a/1527820/411632
      const random = min => max => {
      const min_ = Math.ceil (min)
      const max_ = Math.floor (max)

      return Math.floor (Math.random () * (max - min + 1)) + min
      }

      //////////////////////////////////////////////////////////////

      const countries = ['Belgium', 'Uk']
      const years = ['2019', '2018', '2017']


      const output1 = lift2 (year => country => ({
      country,
      year,
      red: random (1) (255),
      orange: random (1) (255),
      green: random (1) (255)
      })) (years) (countries)

      const output2 = Object.values (
      output1.reduce ((o, { year, red, green, orange, ...rest }) => {
      const {
      red:red_ = 0,
      green:green_ = 0,
      orange:orange_ = 0
      } = o[year] || {}

      o[year] = {
      ...rest,
      country: 'Tot',
      year,
      red: red + red_,
      green: green + green_,
      orange: orange + orange_
      }

      return o
      }, {})
      )

      const output3 = [...output1, ...output2]

      console.log (output3)








      share|improve this answer

































        0














        This is how it works:



        const countries = ['Belgium', 'Uk']
        const years = ['2019', '2018', '2017']
        const colors = ['red', 'orange', 'green']
        const dataset = ;


        countries.forEach((country)=>{
        years.forEach((year)=>{
        const obj = {
        country: country,
        year: year
        }
        colors.forEach((color)=>{
        obj[color] = Math.floor(Math.random() * 300) + 1;
        })
        dataset.push(obj);
        })
        })

        console.log(dataset);


        https://jsfiddle.net/martinmakesitwork/0x1may62/9/






        share|improve this answer
























        • You forgot the totals

          – HMR
          Jan 31 at 10:38



















        0














        const countries = ['Belgium', 'Uk']
        const years = ['2019', '2018', '2017']
        const colors = ['red', 'orange', 'green']
        countries.push('Total');
        result = ;
        function random(min, max) {
        return Math.floor(Math.random() * (max - min)) + min;
        }
        countries.forEach(item => {
        if (item !== 'Total') {
        yearArr = ;
        years.forEach(y => {
        obj = {
        country: item,
        year: y
        }
        colors.forEach(c => {
        obj[c] = random(0, 300)
        })
        result.push(obj)
        yearArr.push(obj)
        })
        }
        })
        years.forEach(y => {
        obj = result.filter(({ year, country }) => (year === y && country !== 'total'))
        .reduce((a, b) => ({ country: 'total', year: a.year, red: a.red + b.red,
        orange: a.orange + b.orange, green: a.green + b.green }))
        result.push(obj)
        })
        console.log(result);





        share|improve this answer
























          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54458127%2fbuild-an-array-of-objects-from-some-arrays%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          7 Answers
          7






          active

          oldest

          votes








          7 Answers
          7






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          My solution






          const countries = ['Belgium', 'Uk'];
          const years = ['2019', '2018', '2017'];
          const colors = ['red', 'orange', 'green'];

          const min = 0;
          const max = 300;

          console.log(getTotal(
          getResult(countries, years, colors),
          colors
          ));

          function getResult(countries, years, colors) {
          const result = ;
          countries.forEach(country => {
          years.forEach(year => {
          const item = {
          country: country,
          year: year
          };
          colors.forEach(color => {
          item[color] = random(min, max);
          });
          result.push(item);
          });
          });
          return result;
          }

          function getTotal(data, colors) {
          const total = {};
          data.forEach(item => {
          if (typeof total[item.year] === 'undefined') {
          total[item.year] = {};
          colors.forEach(color => {
          total[item.year][color] = item[color];
          });
          } else {
          colors.forEach(color => {
          total[item.year][color] += item[color];
          });
          }
          });
          for (var totalItem in total) {
          data.push({country: 'Tot', year: totalItem, ...total[totalItem]});
          }
          return data;
          }

          function random(min, max) {
          return Math.floor(Math.random() * (max - min)) + min;
          }








          share|improve this answer






























            2














            My solution






            const countries = ['Belgium', 'Uk'];
            const years = ['2019', '2018', '2017'];
            const colors = ['red', 'orange', 'green'];

            const min = 0;
            const max = 300;

            console.log(getTotal(
            getResult(countries, years, colors),
            colors
            ));

            function getResult(countries, years, colors) {
            const result = ;
            countries.forEach(country => {
            years.forEach(year => {
            const item = {
            country: country,
            year: year
            };
            colors.forEach(color => {
            item[color] = random(min, max);
            });
            result.push(item);
            });
            });
            return result;
            }

            function getTotal(data, colors) {
            const total = {};
            data.forEach(item => {
            if (typeof total[item.year] === 'undefined') {
            total[item.year] = {};
            colors.forEach(color => {
            total[item.year][color] = item[color];
            });
            } else {
            colors.forEach(color => {
            total[item.year][color] += item[color];
            });
            }
            });
            for (var totalItem in total) {
            data.push({country: 'Tot', year: totalItem, ...total[totalItem]});
            }
            return data;
            }

            function random(min, max) {
            return Math.floor(Math.random() * (max - min)) + min;
            }








            share|improve this answer




























              2












              2








              2







              My solution






              const countries = ['Belgium', 'Uk'];
              const years = ['2019', '2018', '2017'];
              const colors = ['red', 'orange', 'green'];

              const min = 0;
              const max = 300;

              console.log(getTotal(
              getResult(countries, years, colors),
              colors
              ));

              function getResult(countries, years, colors) {
              const result = ;
              countries.forEach(country => {
              years.forEach(year => {
              const item = {
              country: country,
              year: year
              };
              colors.forEach(color => {
              item[color] = random(min, max);
              });
              result.push(item);
              });
              });
              return result;
              }

              function getTotal(data, colors) {
              const total = {};
              data.forEach(item => {
              if (typeof total[item.year] === 'undefined') {
              total[item.year] = {};
              colors.forEach(color => {
              total[item.year][color] = item[color];
              });
              } else {
              colors.forEach(color => {
              total[item.year][color] += item[color];
              });
              }
              });
              for (var totalItem in total) {
              data.push({country: 'Tot', year: totalItem, ...total[totalItem]});
              }
              return data;
              }

              function random(min, max) {
              return Math.floor(Math.random() * (max - min)) + min;
              }








              share|improve this answer















              My solution






              const countries = ['Belgium', 'Uk'];
              const years = ['2019', '2018', '2017'];
              const colors = ['red', 'orange', 'green'];

              const min = 0;
              const max = 300;

              console.log(getTotal(
              getResult(countries, years, colors),
              colors
              ));

              function getResult(countries, years, colors) {
              const result = ;
              countries.forEach(country => {
              years.forEach(year => {
              const item = {
              country: country,
              year: year
              };
              colors.forEach(color => {
              item[color] = random(min, max);
              });
              result.push(item);
              });
              });
              return result;
              }

              function getTotal(data, colors) {
              const total = {};
              data.forEach(item => {
              if (typeof total[item.year] === 'undefined') {
              total[item.year] = {};
              colors.forEach(color => {
              total[item.year][color] = item[color];
              });
              } else {
              colors.forEach(color => {
              total[item.year][color] += item[color];
              });
              }
              });
              for (var totalItem in total) {
              data.push({country: 'Tot', year: totalItem, ...total[totalItem]});
              }
              return data;
              }

              function random(min, max) {
              return Math.floor(Math.random() * (max - min)) + min;
              }








              const countries = ['Belgium', 'Uk'];
              const years = ['2019', '2018', '2017'];
              const colors = ['red', 'orange', 'green'];

              const min = 0;
              const max = 300;

              console.log(getTotal(
              getResult(countries, years, colors),
              colors
              ));

              function getResult(countries, years, colors) {
              const result = ;
              countries.forEach(country => {
              years.forEach(year => {
              const item = {
              country: country,
              year: year
              };
              colors.forEach(color => {
              item[color] = random(min, max);
              });
              result.push(item);
              });
              });
              return result;
              }

              function getTotal(data, colors) {
              const total = {};
              data.forEach(item => {
              if (typeof total[item.year] === 'undefined') {
              total[item.year] = {};
              colors.forEach(color => {
              total[item.year][color] = item[color];
              });
              } else {
              colors.forEach(color => {
              total[item.year][color] += item[color];
              });
              }
              });
              for (var totalItem in total) {
              data.push({country: 'Tot', year: totalItem, ...total[totalItem]});
              }
              return data;
              }

              function random(min, max) {
              return Math.floor(Math.random() * (max - min)) + min;
              }





              const countries = ['Belgium', 'Uk'];
              const years = ['2019', '2018', '2017'];
              const colors = ['red', 'orange', 'green'];

              const min = 0;
              const max = 300;

              console.log(getTotal(
              getResult(countries, years, colors),
              colors
              ));

              function getResult(countries, years, colors) {
              const result = ;
              countries.forEach(country => {
              years.forEach(year => {
              const item = {
              country: country,
              year: year
              };
              colors.forEach(color => {
              item[color] = random(min, max);
              });
              result.push(item);
              });
              });
              return result;
              }

              function getTotal(data, colors) {
              const total = {};
              data.forEach(item => {
              if (typeof total[item.year] === 'undefined') {
              total[item.year] = {};
              colors.forEach(color => {
              total[item.year][color] = item[color];
              });
              } else {
              colors.forEach(color => {
              total[item.year][color] += item[color];
              });
              }
              });
              for (var totalItem in total) {
              data.push({country: 'Tot', year: totalItem, ...total[totalItem]});
              }
              return data;
              }

              function random(min, max) {
              return Math.floor(Math.random() * (max - min)) + min;
              }






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Jan 31 at 10:41

























              answered Jan 31 at 10:36









              eustatoseustatos

              368312




              368312

























                  4














                  You could get a cartesian result of countries and years, get all totals and build the missing total objects.






                  function getCartesian(object) {
                  return Object.entries(object).reduce((r, [k, v]) => {
                  var temp = ;
                  r.forEach(s =>
                  (Array.isArray(v) ? v : [v]).forEach(w =>
                  (w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
                  temp.push(Object.assign({}, s, { [k]: x }))
                  )
                  )
                  );
                  return temp;
                  }, [{}]);
                  }

                  function random(min, max) {
                  return Math.floor(Math.random() * (max - min)) + min;
                  }

                  const
                  countries = ['Belgium', 'Uk'],
                  years = ['2019', '2018', '2017'],
                  colors = ['red', 'orange', 'green'],
                  result = getCartesian({ country: countries, year: years })
                  .map(o => Object.assign(o, ...colors.map(k => ({ [k]: random(0, 300) })))),
                  totals = result.reduce((r, o) => (colors.forEach(color => {
                  r[o.year] = r[o.year] || {};
                  r[o.year][color] = (r[o.year][color] || 0) + o[color];
                  }), r), {});

                  result.push(...years.map(year => Object.assign(
                  { country: 'TOT', year },
                  ...colors.map(color => ({ [color]: totals[year][color] }))
                  )));

                  console.log(result);

                  .as-console-wrapper { max-height: 100% !important; top: 0; }








                  share|improve this answer


























                  • That fancy name cartesian though.. nice"

                    – Alvin Theodora
                    Jan 31 at 10:41
















                  4














                  You could get a cartesian result of countries and years, get all totals and build the missing total objects.






                  function getCartesian(object) {
                  return Object.entries(object).reduce((r, [k, v]) => {
                  var temp = ;
                  r.forEach(s =>
                  (Array.isArray(v) ? v : [v]).forEach(w =>
                  (w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
                  temp.push(Object.assign({}, s, { [k]: x }))
                  )
                  )
                  );
                  return temp;
                  }, [{}]);
                  }

                  function random(min, max) {
                  return Math.floor(Math.random() * (max - min)) + min;
                  }

                  const
                  countries = ['Belgium', 'Uk'],
                  years = ['2019', '2018', '2017'],
                  colors = ['red', 'orange', 'green'],
                  result = getCartesian({ country: countries, year: years })
                  .map(o => Object.assign(o, ...colors.map(k => ({ [k]: random(0, 300) })))),
                  totals = result.reduce((r, o) => (colors.forEach(color => {
                  r[o.year] = r[o.year] || {};
                  r[o.year][color] = (r[o.year][color] || 0) + o[color];
                  }), r), {});

                  result.push(...years.map(year => Object.assign(
                  { country: 'TOT', year },
                  ...colors.map(color => ({ [color]: totals[year][color] }))
                  )));

                  console.log(result);

                  .as-console-wrapper { max-height: 100% !important; top: 0; }








                  share|improve this answer


























                  • That fancy name cartesian though.. nice"

                    – Alvin Theodora
                    Jan 31 at 10:41














                  4












                  4








                  4







                  You could get a cartesian result of countries and years, get all totals and build the missing total objects.






                  function getCartesian(object) {
                  return Object.entries(object).reduce((r, [k, v]) => {
                  var temp = ;
                  r.forEach(s =>
                  (Array.isArray(v) ? v : [v]).forEach(w =>
                  (w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
                  temp.push(Object.assign({}, s, { [k]: x }))
                  )
                  )
                  );
                  return temp;
                  }, [{}]);
                  }

                  function random(min, max) {
                  return Math.floor(Math.random() * (max - min)) + min;
                  }

                  const
                  countries = ['Belgium', 'Uk'],
                  years = ['2019', '2018', '2017'],
                  colors = ['red', 'orange', 'green'],
                  result = getCartesian({ country: countries, year: years })
                  .map(o => Object.assign(o, ...colors.map(k => ({ [k]: random(0, 300) })))),
                  totals = result.reduce((r, o) => (colors.forEach(color => {
                  r[o.year] = r[o.year] || {};
                  r[o.year][color] = (r[o.year][color] || 0) + o[color];
                  }), r), {});

                  result.push(...years.map(year => Object.assign(
                  { country: 'TOT', year },
                  ...colors.map(color => ({ [color]: totals[year][color] }))
                  )));

                  console.log(result);

                  .as-console-wrapper { max-height: 100% !important; top: 0; }








                  share|improve this answer















                  You could get a cartesian result of countries and years, get all totals and build the missing total objects.






                  function getCartesian(object) {
                  return Object.entries(object).reduce((r, [k, v]) => {
                  var temp = ;
                  r.forEach(s =>
                  (Array.isArray(v) ? v : [v]).forEach(w =>
                  (w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
                  temp.push(Object.assign({}, s, { [k]: x }))
                  )
                  )
                  );
                  return temp;
                  }, [{}]);
                  }

                  function random(min, max) {
                  return Math.floor(Math.random() * (max - min)) + min;
                  }

                  const
                  countries = ['Belgium', 'Uk'],
                  years = ['2019', '2018', '2017'],
                  colors = ['red', 'orange', 'green'],
                  result = getCartesian({ country: countries, year: years })
                  .map(o => Object.assign(o, ...colors.map(k => ({ [k]: random(0, 300) })))),
                  totals = result.reduce((r, o) => (colors.forEach(color => {
                  r[o.year] = r[o.year] || {};
                  r[o.year][color] = (r[o.year][color] || 0) + o[color];
                  }), r), {});

                  result.push(...years.map(year => Object.assign(
                  { country: 'TOT', year },
                  ...colors.map(color => ({ [color]: totals[year][color] }))
                  )));

                  console.log(result);

                  .as-console-wrapper { max-height: 100% !important; top: 0; }








                  function getCartesian(object) {
                  return Object.entries(object).reduce((r, [k, v]) => {
                  var temp = ;
                  r.forEach(s =>
                  (Array.isArray(v) ? v : [v]).forEach(w =>
                  (w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
                  temp.push(Object.assign({}, s, { [k]: x }))
                  )
                  )
                  );
                  return temp;
                  }, [{}]);
                  }

                  function random(min, max) {
                  return Math.floor(Math.random() * (max - min)) + min;
                  }

                  const
                  countries = ['Belgium', 'Uk'],
                  years = ['2019', '2018', '2017'],
                  colors = ['red', 'orange', 'green'],
                  result = getCartesian({ country: countries, year: years })
                  .map(o => Object.assign(o, ...colors.map(k => ({ [k]: random(0, 300) })))),
                  totals = result.reduce((r, o) => (colors.forEach(color => {
                  r[o.year] = r[o.year] || {};
                  r[o.year][color] = (r[o.year][color] || 0) + o[color];
                  }), r), {});

                  result.push(...years.map(year => Object.assign(
                  { country: 'TOT', year },
                  ...colors.map(color => ({ [color]: totals[year][color] }))
                  )));

                  console.log(result);

                  .as-console-wrapper { max-height: 100% !important; top: 0; }





                  function getCartesian(object) {
                  return Object.entries(object).reduce((r, [k, v]) => {
                  var temp = ;
                  r.forEach(s =>
                  (Array.isArray(v) ? v : [v]).forEach(w =>
                  (w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
                  temp.push(Object.assign({}, s, { [k]: x }))
                  )
                  )
                  );
                  return temp;
                  }, [{}]);
                  }

                  function random(min, max) {
                  return Math.floor(Math.random() * (max - min)) + min;
                  }

                  const
                  countries = ['Belgium', 'Uk'],
                  years = ['2019', '2018', '2017'],
                  colors = ['red', 'orange', 'green'],
                  result = getCartesian({ country: countries, year: years })
                  .map(o => Object.assign(o, ...colors.map(k => ({ [k]: random(0, 300) })))),
                  totals = result.reduce((r, o) => (colors.forEach(color => {
                  r[o.year] = r[o.year] || {};
                  r[o.year][color] = (r[o.year][color] || 0) + o[color];
                  }), r), {});

                  result.push(...years.map(year => Object.assign(
                  { country: 'TOT', year },
                  ...colors.map(color => ({ [color]: totals[year][color] }))
                  )));

                  console.log(result);

                  .as-console-wrapper { max-height: 100% !important; top: 0; }






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jan 31 at 11:32









                  adiga

                  12.2k62645




                  12.2k62645










                  answered Jan 31 at 10:34









                  Nina ScholzNina Scholz

                  196k15108179




                  196k15108179













                  • That fancy name cartesian though.. nice"

                    – Alvin Theodora
                    Jan 31 at 10:41



















                  • That fancy name cartesian though.. nice"

                    – Alvin Theodora
                    Jan 31 at 10:41

















                  That fancy name cartesian though.. nice"

                  – Alvin Theodora
                  Jan 31 at 10:41





                  That fancy name cartesian though.. nice"

                  – Alvin Theodora
                  Jan 31 at 10:41











                  3














                  You could do something like this using forEach and reduce




                  • Get all the possible combination of countries and years in combo


                  • reduce the combo and get the sum for each color grouped based on the year


                  • concat the combo array and total values grouped from the reduce





                  const countries = ['Belgium', 'Uk']
                  const years = ['2019', '2018', '2017']
                  const colors = ['red', 'orange', 'green']

                  function random(min, max) {
                  return Math.floor(Math.random() * (max - min + 1)) + min;
                  }

                  const combo = ;

                  countries.forEach(country => {
                  years.forEach(year => {

                  const obj = {country,year};
                  colors.forEach(color => {
                  obj[color] = random(1, 10)
                  })

                  combo.push(obj)
                  })
                  })

                  const total = combo.reduce((acc, {year, country,...rest}) => {
                  acc[year] = acc[year] || {year,country: 'Tot'};

                  for (let color in rest) {
                  acc[year][color] = (acc[year][color] + rest[color]) || rest[color]
                  }

                  return acc;
                  }, {})


                  const final = combo.concat(Object.values(total))

                  console.log(final)








                  share|improve this answer





















                  • 2





                    elegant use spread operator, destructor and OR. Save in their recipes. Thanks.

                    – eustatos
                    Jan 31 at 10:47
















                  3














                  You could do something like this using forEach and reduce




                  • Get all the possible combination of countries and years in combo


                  • reduce the combo and get the sum for each color grouped based on the year


                  • concat the combo array and total values grouped from the reduce





                  const countries = ['Belgium', 'Uk']
                  const years = ['2019', '2018', '2017']
                  const colors = ['red', 'orange', 'green']

                  function random(min, max) {
                  return Math.floor(Math.random() * (max - min + 1)) + min;
                  }

                  const combo = ;

                  countries.forEach(country => {
                  years.forEach(year => {

                  const obj = {country,year};
                  colors.forEach(color => {
                  obj[color] = random(1, 10)
                  })

                  combo.push(obj)
                  })
                  })

                  const total = combo.reduce((acc, {year, country,...rest}) => {
                  acc[year] = acc[year] || {year,country: 'Tot'};

                  for (let color in rest) {
                  acc[year][color] = (acc[year][color] + rest[color]) || rest[color]
                  }

                  return acc;
                  }, {})


                  const final = combo.concat(Object.values(total))

                  console.log(final)








                  share|improve this answer





















                  • 2





                    elegant use spread operator, destructor and OR. Save in their recipes. Thanks.

                    – eustatos
                    Jan 31 at 10:47














                  3












                  3








                  3







                  You could do something like this using forEach and reduce




                  • Get all the possible combination of countries and years in combo


                  • reduce the combo and get the sum for each color grouped based on the year


                  • concat the combo array and total values grouped from the reduce





                  const countries = ['Belgium', 'Uk']
                  const years = ['2019', '2018', '2017']
                  const colors = ['red', 'orange', 'green']

                  function random(min, max) {
                  return Math.floor(Math.random() * (max - min + 1)) + min;
                  }

                  const combo = ;

                  countries.forEach(country => {
                  years.forEach(year => {

                  const obj = {country,year};
                  colors.forEach(color => {
                  obj[color] = random(1, 10)
                  })

                  combo.push(obj)
                  })
                  })

                  const total = combo.reduce((acc, {year, country,...rest}) => {
                  acc[year] = acc[year] || {year,country: 'Tot'};

                  for (let color in rest) {
                  acc[year][color] = (acc[year][color] + rest[color]) || rest[color]
                  }

                  return acc;
                  }, {})


                  const final = combo.concat(Object.values(total))

                  console.log(final)








                  share|improve this answer















                  You could do something like this using forEach and reduce




                  • Get all the possible combination of countries and years in combo


                  • reduce the combo and get the sum for each color grouped based on the year


                  • concat the combo array and total values grouped from the reduce





                  const countries = ['Belgium', 'Uk']
                  const years = ['2019', '2018', '2017']
                  const colors = ['red', 'orange', 'green']

                  function random(min, max) {
                  return Math.floor(Math.random() * (max - min + 1)) + min;
                  }

                  const combo = ;

                  countries.forEach(country => {
                  years.forEach(year => {

                  const obj = {country,year};
                  colors.forEach(color => {
                  obj[color] = random(1, 10)
                  })

                  combo.push(obj)
                  })
                  })

                  const total = combo.reduce((acc, {year, country,...rest}) => {
                  acc[year] = acc[year] || {year,country: 'Tot'};

                  for (let color in rest) {
                  acc[year][color] = (acc[year][color] + rest[color]) || rest[color]
                  }

                  return acc;
                  }, {})


                  const final = combo.concat(Object.values(total))

                  console.log(final)








                  const countries = ['Belgium', 'Uk']
                  const years = ['2019', '2018', '2017']
                  const colors = ['red', 'orange', 'green']

                  function random(min, max) {
                  return Math.floor(Math.random() * (max - min + 1)) + min;
                  }

                  const combo = ;

                  countries.forEach(country => {
                  years.forEach(year => {

                  const obj = {country,year};
                  colors.forEach(color => {
                  obj[color] = random(1, 10)
                  })

                  combo.push(obj)
                  })
                  })

                  const total = combo.reduce((acc, {year, country,...rest}) => {
                  acc[year] = acc[year] || {year,country: 'Tot'};

                  for (let color in rest) {
                  acc[year][color] = (acc[year][color] + rest[color]) || rest[color]
                  }

                  return acc;
                  }, {})


                  const final = combo.concat(Object.values(total))

                  console.log(final)





                  const countries = ['Belgium', 'Uk']
                  const years = ['2019', '2018', '2017']
                  const colors = ['red', 'orange', 'green']

                  function random(min, max) {
                  return Math.floor(Math.random() * (max - min + 1)) + min;
                  }

                  const combo = ;

                  countries.forEach(country => {
                  years.forEach(year => {

                  const obj = {country,year};
                  colors.forEach(color => {
                  obj[color] = random(1, 10)
                  })

                  combo.push(obj)
                  })
                  })

                  const total = combo.reduce((acc, {year, country,...rest}) => {
                  acc[year] = acc[year] || {year,country: 'Tot'};

                  for (let color in rest) {
                  acc[year][color] = (acc[year][color] + rest[color]) || rest[color]
                  }

                  return acc;
                  }, {})


                  const final = combo.concat(Object.values(total))

                  console.log(final)






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jan 31 at 10:45

























                  answered Jan 31 at 10:38









                  adigaadiga

                  12.2k62645




                  12.2k62645








                  • 2





                    elegant use spread operator, destructor and OR. Save in their recipes. Thanks.

                    – eustatos
                    Jan 31 at 10:47














                  • 2





                    elegant use spread operator, destructor and OR. Save in their recipes. Thanks.

                    – eustatos
                    Jan 31 at 10:47








                  2




                  2





                  elegant use spread operator, destructor and OR. Save in their recipes. Thanks.

                  – eustatos
                  Jan 31 at 10:47





                  elegant use spread operator, destructor and OR. Save in their recipes. Thanks.

                  – eustatos
                  Jan 31 at 10:47











                  1














                  Double reduce and spread operator.



                  For each country and then for each years, we are creating a new json. This json is made of the country + year key and colors we have to loop on aswell. Then we add the total.






                  function random(min, max) {
                  return Math.floor(Math.random() * (max - min)) + min;
                  }

                  const countries = ['Belgium', 'Uk'];
                  const years = ['2019', '2018', '2017'];
                  const colors = ['red', 'orange', 'green'];

                  const arr = countries.reduce((tmp, x) => [
                  ...tmp,

                  ...years.map(y => colors.reduce((json, z) => {
                  json[z] = random(0, 255);

                  return json;
                  }, {
                  country: x,
                  year: y,
                  })),
                  ], );

                  // add the Tot
                  const arrWithTotal = [
                  ...arr,

                  ...years.map(y => colors.reduce((json, x) => {
                  json[x] = arr.reduce((tmp, z) => z.year === y ? tmp + z[x] : tmp, 0);

                  return json;
                  }, {
                  country: 'Tot',
                  year: y,
                  })),
                  ];

                  console.log(arrWithTotal);








                  share|improve this answer






























                    1














                    Double reduce and spread operator.



                    For each country and then for each years, we are creating a new json. This json is made of the country + year key and colors we have to loop on aswell. Then we add the total.






                    function random(min, max) {
                    return Math.floor(Math.random() * (max - min)) + min;
                    }

                    const countries = ['Belgium', 'Uk'];
                    const years = ['2019', '2018', '2017'];
                    const colors = ['red', 'orange', 'green'];

                    const arr = countries.reduce((tmp, x) => [
                    ...tmp,

                    ...years.map(y => colors.reduce((json, z) => {
                    json[z] = random(0, 255);

                    return json;
                    }, {
                    country: x,
                    year: y,
                    })),
                    ], );

                    // add the Tot
                    const arrWithTotal = [
                    ...arr,

                    ...years.map(y => colors.reduce((json, x) => {
                    json[x] = arr.reduce((tmp, z) => z.year === y ? tmp + z[x] : tmp, 0);

                    return json;
                    }, {
                    country: 'Tot',
                    year: y,
                    })),
                    ];

                    console.log(arrWithTotal);








                    share|improve this answer




























                      1












                      1








                      1







                      Double reduce and spread operator.



                      For each country and then for each years, we are creating a new json. This json is made of the country + year key and colors we have to loop on aswell. Then we add the total.






                      function random(min, max) {
                      return Math.floor(Math.random() * (max - min)) + min;
                      }

                      const countries = ['Belgium', 'Uk'];
                      const years = ['2019', '2018', '2017'];
                      const colors = ['red', 'orange', 'green'];

                      const arr = countries.reduce((tmp, x) => [
                      ...tmp,

                      ...years.map(y => colors.reduce((json, z) => {
                      json[z] = random(0, 255);

                      return json;
                      }, {
                      country: x,
                      year: y,
                      })),
                      ], );

                      // add the Tot
                      const arrWithTotal = [
                      ...arr,

                      ...years.map(y => colors.reduce((json, x) => {
                      json[x] = arr.reduce((tmp, z) => z.year === y ? tmp + z[x] : tmp, 0);

                      return json;
                      }, {
                      country: 'Tot',
                      year: y,
                      })),
                      ];

                      console.log(arrWithTotal);








                      share|improve this answer















                      Double reduce and spread operator.



                      For each country and then for each years, we are creating a new json. This json is made of the country + year key and colors we have to loop on aswell. Then we add the total.






                      function random(min, max) {
                      return Math.floor(Math.random() * (max - min)) + min;
                      }

                      const countries = ['Belgium', 'Uk'];
                      const years = ['2019', '2018', '2017'];
                      const colors = ['red', 'orange', 'green'];

                      const arr = countries.reduce((tmp, x) => [
                      ...tmp,

                      ...years.map(y => colors.reduce((json, z) => {
                      json[z] = random(0, 255);

                      return json;
                      }, {
                      country: x,
                      year: y,
                      })),
                      ], );

                      // add the Tot
                      const arrWithTotal = [
                      ...arr,

                      ...years.map(y => colors.reduce((json, x) => {
                      json[x] = arr.reduce((tmp, z) => z.year === y ? tmp + z[x] : tmp, 0);

                      return json;
                      }, {
                      country: 'Tot',
                      year: y,
                      })),
                      ];

                      console.log(arrWithTotal);








                      function random(min, max) {
                      return Math.floor(Math.random() * (max - min)) + min;
                      }

                      const countries = ['Belgium', 'Uk'];
                      const years = ['2019', '2018', '2017'];
                      const colors = ['red', 'orange', 'green'];

                      const arr = countries.reduce((tmp, x) => [
                      ...tmp,

                      ...years.map(y => colors.reduce((json, z) => {
                      json[z] = random(0, 255);

                      return json;
                      }, {
                      country: x,
                      year: y,
                      })),
                      ], );

                      // add the Tot
                      const arrWithTotal = [
                      ...arr,

                      ...years.map(y => colors.reduce((json, x) => {
                      json[x] = arr.reduce((tmp, z) => z.year === y ? tmp + z[x] : tmp, 0);

                      return json;
                      }, {
                      country: 'Tot',
                      year: y,
                      })),
                      ];

                      console.log(arrWithTotal);





                      function random(min, max) {
                      return Math.floor(Math.random() * (max - min)) + min;
                      }

                      const countries = ['Belgium', 'Uk'];
                      const years = ['2019', '2018', '2017'];
                      const colors = ['red', 'orange', 'green'];

                      const arr = countries.reduce((tmp, x) => [
                      ...tmp,

                      ...years.map(y => colors.reduce((json, z) => {
                      json[z] = random(0, 255);

                      return json;
                      }, {
                      country: x,
                      year: y,
                      })),
                      ], );

                      // add the Tot
                      const arrWithTotal = [
                      ...arr,

                      ...years.map(y => colors.reduce((json, x) => {
                      json[x] = arr.reduce((tmp, z) => z.year === y ? tmp + z[x] : tmp, 0);

                      return json;
                      }, {
                      country: 'Tot',
                      year: y,
                      })),
                      ];

                      console.log(arrWithTotal);






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Jan 31 at 11:17

























                      answered Jan 31 at 11:07









                      Grégory NEUTGrégory NEUT

                      9,73721941




                      9,73721941























                          1














                          Here's a purely functional solution. It uses local mutation in Array#reduce, but the computation itself is pure:






                          const ap = fs => xs => xs.flatMap (x => fs.map (f => f (x)))
                          const lift2 = f => xs => ys => ap (xs.map (f)) (ys)

                          // source: https://stackoverflow.com/a/1527820/411632
                          const random = min => max => {
                          const min_ = Math.ceil (min)
                          const max_ = Math.floor (max)

                          return Math.floor (Math.random () * (max - min + 1)) + min
                          }

                          //////////////////////////////////////////////////////////////

                          const countries = ['Belgium', 'Uk']
                          const years = ['2019', '2018', '2017']


                          const output1 = lift2 (year => country => ({
                          country,
                          year,
                          red: random (1) (255),
                          orange: random (1) (255),
                          green: random (1) (255)
                          })) (years) (countries)

                          const output2 = Object.values (
                          output1.reduce ((o, { year, red, green, orange, ...rest }) => {
                          const {
                          red:red_ = 0,
                          green:green_ = 0,
                          orange:orange_ = 0
                          } = o[year] || {}

                          o[year] = {
                          ...rest,
                          country: 'Tot',
                          year,
                          red: red + red_,
                          green: green + green_,
                          orange: orange + orange_
                          }

                          return o
                          }, {})
                          )

                          const output3 = [...output1, ...output2]

                          console.log (output3)








                          share|improve this answer






























                            1














                            Here's a purely functional solution. It uses local mutation in Array#reduce, but the computation itself is pure:






                            const ap = fs => xs => xs.flatMap (x => fs.map (f => f (x)))
                            const lift2 = f => xs => ys => ap (xs.map (f)) (ys)

                            // source: https://stackoverflow.com/a/1527820/411632
                            const random = min => max => {
                            const min_ = Math.ceil (min)
                            const max_ = Math.floor (max)

                            return Math.floor (Math.random () * (max - min + 1)) + min
                            }

                            //////////////////////////////////////////////////////////////

                            const countries = ['Belgium', 'Uk']
                            const years = ['2019', '2018', '2017']


                            const output1 = lift2 (year => country => ({
                            country,
                            year,
                            red: random (1) (255),
                            orange: random (1) (255),
                            green: random (1) (255)
                            })) (years) (countries)

                            const output2 = Object.values (
                            output1.reduce ((o, { year, red, green, orange, ...rest }) => {
                            const {
                            red:red_ = 0,
                            green:green_ = 0,
                            orange:orange_ = 0
                            } = o[year] || {}

                            o[year] = {
                            ...rest,
                            country: 'Tot',
                            year,
                            red: red + red_,
                            green: green + green_,
                            orange: orange + orange_
                            }

                            return o
                            }, {})
                            )

                            const output3 = [...output1, ...output2]

                            console.log (output3)








                            share|improve this answer




























                              1












                              1








                              1







                              Here's a purely functional solution. It uses local mutation in Array#reduce, but the computation itself is pure:






                              const ap = fs => xs => xs.flatMap (x => fs.map (f => f (x)))
                              const lift2 = f => xs => ys => ap (xs.map (f)) (ys)

                              // source: https://stackoverflow.com/a/1527820/411632
                              const random = min => max => {
                              const min_ = Math.ceil (min)
                              const max_ = Math.floor (max)

                              return Math.floor (Math.random () * (max - min + 1)) + min
                              }

                              //////////////////////////////////////////////////////////////

                              const countries = ['Belgium', 'Uk']
                              const years = ['2019', '2018', '2017']


                              const output1 = lift2 (year => country => ({
                              country,
                              year,
                              red: random (1) (255),
                              orange: random (1) (255),
                              green: random (1) (255)
                              })) (years) (countries)

                              const output2 = Object.values (
                              output1.reduce ((o, { year, red, green, orange, ...rest }) => {
                              const {
                              red:red_ = 0,
                              green:green_ = 0,
                              orange:orange_ = 0
                              } = o[year] || {}

                              o[year] = {
                              ...rest,
                              country: 'Tot',
                              year,
                              red: red + red_,
                              green: green + green_,
                              orange: orange + orange_
                              }

                              return o
                              }, {})
                              )

                              const output3 = [...output1, ...output2]

                              console.log (output3)








                              share|improve this answer















                              Here's a purely functional solution. It uses local mutation in Array#reduce, but the computation itself is pure:






                              const ap = fs => xs => xs.flatMap (x => fs.map (f => f (x)))
                              const lift2 = f => xs => ys => ap (xs.map (f)) (ys)

                              // source: https://stackoverflow.com/a/1527820/411632
                              const random = min => max => {
                              const min_ = Math.ceil (min)
                              const max_ = Math.floor (max)

                              return Math.floor (Math.random () * (max - min + 1)) + min
                              }

                              //////////////////////////////////////////////////////////////

                              const countries = ['Belgium', 'Uk']
                              const years = ['2019', '2018', '2017']


                              const output1 = lift2 (year => country => ({
                              country,
                              year,
                              red: random (1) (255),
                              orange: random (1) (255),
                              green: random (1) (255)
                              })) (years) (countries)

                              const output2 = Object.values (
                              output1.reduce ((o, { year, red, green, orange, ...rest }) => {
                              const {
                              red:red_ = 0,
                              green:green_ = 0,
                              orange:orange_ = 0
                              } = o[year] || {}

                              o[year] = {
                              ...rest,
                              country: 'Tot',
                              year,
                              red: red + red_,
                              green: green + green_,
                              orange: orange + orange_
                              }

                              return o
                              }, {})
                              )

                              const output3 = [...output1, ...output2]

                              console.log (output3)








                              const ap = fs => xs => xs.flatMap (x => fs.map (f => f (x)))
                              const lift2 = f => xs => ys => ap (xs.map (f)) (ys)

                              // source: https://stackoverflow.com/a/1527820/411632
                              const random = min => max => {
                              const min_ = Math.ceil (min)
                              const max_ = Math.floor (max)

                              return Math.floor (Math.random () * (max - min + 1)) + min
                              }

                              //////////////////////////////////////////////////////////////

                              const countries = ['Belgium', 'Uk']
                              const years = ['2019', '2018', '2017']


                              const output1 = lift2 (year => country => ({
                              country,
                              year,
                              red: random (1) (255),
                              orange: random (1) (255),
                              green: random (1) (255)
                              })) (years) (countries)

                              const output2 = Object.values (
                              output1.reduce ((o, { year, red, green, orange, ...rest }) => {
                              const {
                              red:red_ = 0,
                              green:green_ = 0,
                              orange:orange_ = 0
                              } = o[year] || {}

                              o[year] = {
                              ...rest,
                              country: 'Tot',
                              year,
                              red: red + red_,
                              green: green + green_,
                              orange: orange + orange_
                              }

                              return o
                              }, {})
                              )

                              const output3 = [...output1, ...output2]

                              console.log (output3)





                              const ap = fs => xs => xs.flatMap (x => fs.map (f => f (x)))
                              const lift2 = f => xs => ys => ap (xs.map (f)) (ys)

                              // source: https://stackoverflow.com/a/1527820/411632
                              const random = min => max => {
                              const min_ = Math.ceil (min)
                              const max_ = Math.floor (max)

                              return Math.floor (Math.random () * (max - min + 1)) + min
                              }

                              //////////////////////////////////////////////////////////////

                              const countries = ['Belgium', 'Uk']
                              const years = ['2019', '2018', '2017']


                              const output1 = lift2 (year => country => ({
                              country,
                              year,
                              red: random (1) (255),
                              orange: random (1) (255),
                              green: random (1) (255)
                              })) (years) (countries)

                              const output2 = Object.values (
                              output1.reduce ((o, { year, red, green, orange, ...rest }) => {
                              const {
                              red:red_ = 0,
                              green:green_ = 0,
                              orange:orange_ = 0
                              } = o[year] || {}

                              o[year] = {
                              ...rest,
                              country: 'Tot',
                              year,
                              red: red + red_,
                              green: green + green_,
                              orange: orange + orange_
                              }

                              return o
                              }, {})
                              )

                              const output3 = [...output1, ...output2]

                              console.log (output3)






                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Jan 31 at 11:23

























                              answered Jan 31 at 11:03









                              Matías FidemraizerMatías Fidemraizer

                              49.7k1285149




                              49.7k1285149























                                  0














                                  This is how it works:



                                  const countries = ['Belgium', 'Uk']
                                  const years = ['2019', '2018', '2017']
                                  const colors = ['red', 'orange', 'green']
                                  const dataset = ;


                                  countries.forEach((country)=>{
                                  years.forEach((year)=>{
                                  const obj = {
                                  country: country,
                                  year: year
                                  }
                                  colors.forEach((color)=>{
                                  obj[color] = Math.floor(Math.random() * 300) + 1;
                                  })
                                  dataset.push(obj);
                                  })
                                  })

                                  console.log(dataset);


                                  https://jsfiddle.net/martinmakesitwork/0x1may62/9/






                                  share|improve this answer
























                                  • You forgot the totals

                                    – HMR
                                    Jan 31 at 10:38
















                                  0














                                  This is how it works:



                                  const countries = ['Belgium', 'Uk']
                                  const years = ['2019', '2018', '2017']
                                  const colors = ['red', 'orange', 'green']
                                  const dataset = ;


                                  countries.forEach((country)=>{
                                  years.forEach((year)=>{
                                  const obj = {
                                  country: country,
                                  year: year
                                  }
                                  colors.forEach((color)=>{
                                  obj[color] = Math.floor(Math.random() * 300) + 1;
                                  })
                                  dataset.push(obj);
                                  })
                                  })

                                  console.log(dataset);


                                  https://jsfiddle.net/martinmakesitwork/0x1may62/9/






                                  share|improve this answer
























                                  • You forgot the totals

                                    – HMR
                                    Jan 31 at 10:38














                                  0












                                  0








                                  0







                                  This is how it works:



                                  const countries = ['Belgium', 'Uk']
                                  const years = ['2019', '2018', '2017']
                                  const colors = ['red', 'orange', 'green']
                                  const dataset = ;


                                  countries.forEach((country)=>{
                                  years.forEach((year)=>{
                                  const obj = {
                                  country: country,
                                  year: year
                                  }
                                  colors.forEach((color)=>{
                                  obj[color] = Math.floor(Math.random() * 300) + 1;
                                  })
                                  dataset.push(obj);
                                  })
                                  })

                                  console.log(dataset);


                                  https://jsfiddle.net/martinmakesitwork/0x1may62/9/






                                  share|improve this answer













                                  This is how it works:



                                  const countries = ['Belgium', 'Uk']
                                  const years = ['2019', '2018', '2017']
                                  const colors = ['red', 'orange', 'green']
                                  const dataset = ;


                                  countries.forEach((country)=>{
                                  years.forEach((year)=>{
                                  const obj = {
                                  country: country,
                                  year: year
                                  }
                                  colors.forEach((color)=>{
                                  obj[color] = Math.floor(Math.random() * 300) + 1;
                                  })
                                  dataset.push(obj);
                                  })
                                  })

                                  console.log(dataset);


                                  https://jsfiddle.net/martinmakesitwork/0x1may62/9/







                                  share|improve this answer












                                  share|improve this answer



                                  share|improve this answer










                                  answered Jan 31 at 10:29









                                  martinmakesitworkmartinmakesitwork

                                  364




                                  364













                                  • You forgot the totals

                                    – HMR
                                    Jan 31 at 10:38



















                                  • You forgot the totals

                                    – HMR
                                    Jan 31 at 10:38

















                                  You forgot the totals

                                  – HMR
                                  Jan 31 at 10:38





                                  You forgot the totals

                                  – HMR
                                  Jan 31 at 10:38











                                  0














                                  const countries = ['Belgium', 'Uk']
                                  const years = ['2019', '2018', '2017']
                                  const colors = ['red', 'orange', 'green']
                                  countries.push('Total');
                                  result = ;
                                  function random(min, max) {
                                  return Math.floor(Math.random() * (max - min)) + min;
                                  }
                                  countries.forEach(item => {
                                  if (item !== 'Total') {
                                  yearArr = ;
                                  years.forEach(y => {
                                  obj = {
                                  country: item,
                                  year: y
                                  }
                                  colors.forEach(c => {
                                  obj[c] = random(0, 300)
                                  })
                                  result.push(obj)
                                  yearArr.push(obj)
                                  })
                                  }
                                  })
                                  years.forEach(y => {
                                  obj = result.filter(({ year, country }) => (year === y && country !== 'total'))
                                  .reduce((a, b) => ({ country: 'total', year: a.year, red: a.red + b.red,
                                  orange: a.orange + b.orange, green: a.green + b.green }))
                                  result.push(obj)
                                  })
                                  console.log(result);





                                  share|improve this answer




























                                    0














                                    const countries = ['Belgium', 'Uk']
                                    const years = ['2019', '2018', '2017']
                                    const colors = ['red', 'orange', 'green']
                                    countries.push('Total');
                                    result = ;
                                    function random(min, max) {
                                    return Math.floor(Math.random() * (max - min)) + min;
                                    }
                                    countries.forEach(item => {
                                    if (item !== 'Total') {
                                    yearArr = ;
                                    years.forEach(y => {
                                    obj = {
                                    country: item,
                                    year: y
                                    }
                                    colors.forEach(c => {
                                    obj[c] = random(0, 300)
                                    })
                                    result.push(obj)
                                    yearArr.push(obj)
                                    })
                                    }
                                    })
                                    years.forEach(y => {
                                    obj = result.filter(({ year, country }) => (year === y && country !== 'total'))
                                    .reduce((a, b) => ({ country: 'total', year: a.year, red: a.red + b.red,
                                    orange: a.orange + b.orange, green: a.green + b.green }))
                                    result.push(obj)
                                    })
                                    console.log(result);





                                    share|improve this answer


























                                      0












                                      0








                                      0







                                      const countries = ['Belgium', 'Uk']
                                      const years = ['2019', '2018', '2017']
                                      const colors = ['red', 'orange', 'green']
                                      countries.push('Total');
                                      result = ;
                                      function random(min, max) {
                                      return Math.floor(Math.random() * (max - min)) + min;
                                      }
                                      countries.forEach(item => {
                                      if (item !== 'Total') {
                                      yearArr = ;
                                      years.forEach(y => {
                                      obj = {
                                      country: item,
                                      year: y
                                      }
                                      colors.forEach(c => {
                                      obj[c] = random(0, 300)
                                      })
                                      result.push(obj)
                                      yearArr.push(obj)
                                      })
                                      }
                                      })
                                      years.forEach(y => {
                                      obj = result.filter(({ year, country }) => (year === y && country !== 'total'))
                                      .reduce((a, b) => ({ country: 'total', year: a.year, red: a.red + b.red,
                                      orange: a.orange + b.orange, green: a.green + b.green }))
                                      result.push(obj)
                                      })
                                      console.log(result);





                                      share|improve this answer













                                      const countries = ['Belgium', 'Uk']
                                      const years = ['2019', '2018', '2017']
                                      const colors = ['red', 'orange', 'green']
                                      countries.push('Total');
                                      result = ;
                                      function random(min, max) {
                                      return Math.floor(Math.random() * (max - min)) + min;
                                      }
                                      countries.forEach(item => {
                                      if (item !== 'Total') {
                                      yearArr = ;
                                      years.forEach(y => {
                                      obj = {
                                      country: item,
                                      year: y
                                      }
                                      colors.forEach(c => {
                                      obj[c] = random(0, 300)
                                      })
                                      result.push(obj)
                                      yearArr.push(obj)
                                      })
                                      }
                                      })
                                      years.forEach(y => {
                                      obj = result.filter(({ year, country }) => (year === y && country !== 'total'))
                                      .reduce((a, b) => ({ country: 'total', year: a.year, red: a.red + b.red,
                                      orange: a.orange + b.orange, green: a.green + b.green }))
                                      result.push(obj)
                                      })
                                      console.log(result);






                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Jan 31 at 15:22









                                      HrishiHrishi

                                      261213




                                      261213






























                                          draft saved

                                          draft discarded




















































                                          Thanks for contributing an answer to Stack Overflow!


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid



                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.


                                          To learn more, see our tips on writing great answers.




                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function () {
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54458127%2fbuild-an-array-of-objects-from-some-arrays%23new-answer', 'question_page');
                                          }
                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown







                                          Popular posts from this blog

                                          MongoDB - Not Authorized To Execute Command

                                          How to fix TextFormField cause rebuild widget in Flutter

                                          Npm cannot find a required file even through it is in the searched directory