javascript merge arrays into a single object

I am trying to merge several arrays into a single object that I can then iterate to use in chart.js datasets. I have a set of data that looks like this:

export const data = [
    {
        'name': 'Flow',
        'values': {
            'sent': 410,
            'responded': 253,
            'secured': 65
        }
    }
] 

(I limited this to just one, but the dataset is much larger)

Then I have several arrays that I've built based on this data:

this.labels = data.map(item => item.name);
this.colors = ['#439ff4', '#5ec3d5', '#a068e5'];
this.responded = data.map(item => item.values.responded);
this.sent = data.map(item => item.values.sent);
this.secured = data.map(item => item.values.secured);

What I need to do is this:

  1. get the key names (responded, sent, secured) as another array
  2. merge the keys, colors, responded, sent, and secured, arrays into an object called datasets.

    this.datasets = [ /* not sure what to do here! */];

Ultimately my chart in chart js is looking for something like this (I have partially hard-coded values at the moment:

datasets: [
    {
        label: 'Sent',
        data: this.sent,
        backgroundColor: '#439ff4'
    },
    {
        label: 'Responded',
        data: this.responded,
        backgroundColor: '#5ec3d5'
    },
    {
        label: 'Secured',
        data: this.secured,
        backgroundColor: '#a068e5'
    }
],

that I would ultimately like to just express as

datasets: this.datasets,

I hope I explained this well enough as to what I am trying to do.

2 answers

  • answered 2018-01-14 07:36 xianshenglu

    i know your target data like this

    datasets: [
    {
        label: 'Sent',
        data: this.sent,
        backgroundColor: '#439ff4'
    },
    {
        label: 'Responded',
        data: this.responded,
        backgroundColor: '#5ec3d5'
    },
    {
        label: 'Secured',
        data: this.secured,
        backgroundColor: '#a068e5'
    }
    ],
    

    but i don't know your primitive data,could you change your question just like this:

    primitiveData:[****]
    

    what can i do?

    targetData:[****]
    

  • answered 2018-01-14 08:30 Sayan Pal

    Assuming that the key names in data.values stays in lowercase and otherwise it is same as datasets[*].label, you can do something like below.

    // the custom type is just for making it more manageable, omit it if you want
    type DatasetItem = { label: string, data: number[], backgroundColor: string };
    
    let datasets: Array<Partial<DatasetItem>> = [
        {
            label: 'Sent',
            backgroundColor: '#439ff4'
        },
        {
            label: 'Responded',
            backgroundColor: '#5ec3d5'
        },
        {
            label: 'Secured',
            backgroundColor: '#a068e5'
        }
    ];    
    
    const data = [
        {
            'name': 'Flow1',
            'values': {
                'sent': 410,
                'responded': 253,
                'secured': 65
            }
        },
        {
            'name': 'Flow2',
            'values': {
                'sent': 411,
                'responded': 254,
                'secured': 66
            }
        }
    ];
    
    datasets.forEach((item) => item.data = data.map((d) => d.values[item.label.toLowerCase()]));    
    console.log(datasets);