devvab
devvab

Reputation: 109

How to transform array in JS into this format

I've this series JS array data (for a chart which needs category and series), how can I transform it into the 2nd format below.

            series: [{
            name: 'Bikes',
            data: [16240314.115]
        }, {
            name: 'Bikes',
            data: [9520869.049]
        }, {
            name: 'Bikes',
            data: [27832356.658]
        }, {
            name: 'Bikes',
            data: [532399.178]
        }, {
            name: 'Clothing',
            data: [1598657.794]
        }, {
            name: 'Clothing',
            data: [135523.664]
        }, {
            name: 'Accessories',
            data: [4347678.462]
        }, {
            name: 'Accessories',
            data: [376470.596]
         }]

Category

                xaxis: {
            categories: ['2011', '2012', '2013', '2014', ' 2013', '2014', '2013', '2014'],
        }

(where every(name,data) pair in the series corresponds to a year in categories correspondingly, so 3 pairs of (Bike,data) corresponds to 3 different year.) into this

 series: [{
            name: 'Bikes',
            data: [16240314.115, 9520869.049, 27832356.658, 532399.178]
        }, {
            name: 'Clothing',
            data: [NaN, NaN, 1598657.794, 135523.664]
        }, {
            name: 'Accessories',
            data: [NaN, NaN, 4347678.462, 376470.596],
        }]

Is there a way to get this output JS array? I need to group the duplicate together & non-duplicate also.

The original data returned from my webapi is below:

            {
            salesByRegQuery: [
                {
                    ProductCategoryKey: 1,
                    EnglishProductCategoryName: "Bikes",
                    SalesTerritoryKey: 6,
                    SalesTerritoryRegion: "Canada",
                    CalendarYear: 2011,
                    Total_Sales: 40806355.42,
                    Total_cost: 24566041.305,
                    Total_Margin: 16240314.115
                },
                {
                    ProductCategoryKey: 1,
                    EnglishProductCategoryName: "Bikes",
                    SalesTerritoryKey: 6,
                    SalesTerritoryRegion: "Canada",
                    CalendarYear: 2012,
                    Total_Sales: 23146211.771,
                    Total_cost: 13625342.722,
                    Total_Margin: 9520869.049
                },
                {
                    ProductCategoryKey: 1,
                    EnglishProductCategoryName: "Bikes",
                    SalesTerritoryKey: 6,
                    SalesTerritoryRegion: "Canada",
                    CalendarYear: 2013,
                    Total_Sales: 67753756.318,
                    Total_cost: 39921399.66,
                    Total_Margin: 27832356.658
                },
                {
                    ProductCategoryKey: 1,
                    EnglishProductCategoryName: "Bikes",
                    SalesTerritoryKey: 6,
                    SalesTerritoryRegion: "Canada",
                    CalendarYear: 2014,
                    Total_Sales: 1248751.14,
                    Total_cost: 716351.962,
                    Total_Margin: 532399.178
                },
                {
                    ProductCategoryKey: 3,
                    EnglishProductCategoryName: "Clothing",
                    SalesTerritoryKey: 6,
                    SalesTerritoryRegion: "Canada",
                    CalendarYear: 2013,
                    Total_Sales: 3573393.8,
                    Total_cost: 1974736.006,
                    Total_Margin: 1598657.794
                },
                {
                    ProductCategoryKey: 3,
                    EnglishProductCategoryName: "Clothing",
                    SalesTerritoryKey: 6,
                    SalesTerritoryRegion: "Canada",
                    CalendarYear: 2014,
                    Total_Sales: 307623.46,
                    Total_cost: 172099.796,
                    Total_Margin: 135523.664
                },
                {
                    ProductCategoryKey: 4,
                    EnglishProductCategoryName: "Accessories",
                    SalesTerritoryKey: 6,
                    SalesTerritoryRegion: "Canada",
                    CalendarYear: 2013,
                    Total_Sales: 6945190.8,
                    Total_cost: 2597512.338,
                    Total_Margin: 4347678.462
                },
                {
                    ProductCategoryKey: 4,
                    EnglishProductCategoryName: "Accessories",
                    SalesTerritoryKey: 6,
                    SalesTerritoryRegion: "Canada",
                    CalendarYear: 2014,
                    Total_Sales: 601392.25,
                    Total_cost: 224921.654,
                    Total_Margin: 376470.596
                }
            ]
        };

And from this JSON, I've taken the series(EnglishProductCategoryName as "name",Total_Margin as "data") and category data(CalendarYear). So, I've got my data in this format so far

series: [{
            name: 'Bikes',
            data: [16240314.115]
        }, {
            name: 'Bikes',
            data: [9520869.049]
        }, {
            name: 'Bikes',
            data: [27832356.658]
        }, {
            name: 'Bikes',
            data: [532399.178]
        }, {
            name: 'Clothing',
            data: [1598657.794]
        }, {
            name: 'Clothing',
            data: [135523.664]
        }, {
            name: 'Accessories',
            data: [4347678.462]
        }, {
            name: 'Accessories',
            data: [376470.596]
         }]

And for the category data, I just need a unique array for the category source for the chart which is easy. I'm stuck with the series part. The codepen is here and I've hard coded the series and category here in the codepen

CodePen For the chart

For every duplicate name, group their values & take the max size data array of the duplicate name & create a new array of same size for non-duplicate name and fill NaN for the year for which data doesn't exist for that non-duplicate name

Upvotes: 1

Views: 70

Answers (2)

Ivan
Ivan

Reputation: 40768

You could create an object that links each class to an object of year -> value key/value pair. This would look like this:

{
  "Bikes": {
    "2011": 16240314.115,
    "2012": 9520869.049,
    "2013": 27832356.658,
    "2014": 532399.178
  },
  "Clothing": {
    "2013": 1598657.794,
    "2014": 135523.664
  },
  "Accessories": {
    "2013": 4347678.462,
    "2014": 376470.596
  }
}

Then you would have to transform each sub-objects into an array filling the missing gaps:

const years = {'2011':0, '2012':1, '2013':2, '2014':3}

const intermediate = series.reduce((res, {name, data}, i) => {
  res[name] = res[name] || {};
  res[name][xaxis.categories[i]] = data[0];
  
  return res;
}, {});

const result = Object.entries(intermediate).map(([name, class_years]) => {
  const data = (new Array(4)).fill(NaN);
  Object.entries(class_years).forEach(([year, value]) => data[years[year]] = value);
  
  return { name, data };
});

console.log(result)
<script>
  const series = [{
    name: 'Bikes',
    data: [16240314.115]
  }, {
    name: 'Bikes',
    data: [9520869.049]
  }, {
    name: 'Bikes',
    data: [27832356.658]
  }, {
    name: 'Bikes',
    data: [532399.178]
  }, {
    name: 'Clothing',
    data: [1598657.794]
  }, {
    name: 'Clothing',
    data: [135523.664]
  }, {
    name: 'Accessories',
    data: [4347678.462]
  }, {
    name: 'Accessories',
    data: [376470.596]
  }];
  const xaxis = {
    categories: ['2011', '2012', '2013', '2014', '2013', '2014', '2013', '2014'],
  }
</script>

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386868

You could get the years in advynce, sort them and use this array as pattern for geeting arrays of NaN value as initial data property and use this array for getting an index for storing the value.

var series = [{ name: 'Bikes', data: [16240314.115] }, { name: 'Bikes', data: [9520869.049] }, { name: 'Bikes', data: [27832356.658] }, { name: 'Bikes', data: [532399.178] }, { name: 'Clothing', data: [1598657.794] }, { name: 'Clothing', data: [135523.664] }, { name: 'Accessories', data: [4347678.462] }, { name: 'Accessories', data: [376470.596] }],
    categories = ['2011', '2012', '2013', '2014', '2013', '2014', '2013', '2014'],
    years = [...new Set(categories)].sort((a, b) => a - b),
    result = series.reduce((r, { name, data }, i) => {
        var temp = r.find(q => q.name === name);
        if (!temp) r.push(temp = { name, data: years.map(_ => NaN) });
        temp.data[years.indexOf(categories[i])] = data[0];
        return r;
    }, []);

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

Upvotes: 1

Related Questions