Search code examples
javascriptarraysangularjssortingjavascript-objects

Sort Filter Comare array of objects in a particular format


Sort my json in format as below :

    [{"x":"Jan-2017","y":41},{"x":"Feb-2017","y":20},{"x":"Mar-2017","y":45},{"x":"Apr-2017","y":29},{"x":"May-2017","y":59},{"x":"Jun-2017","y":378},{"x":"Jul-2017","y":354},{"x":"Aug-2017","y":398},{"x":"Sep-2017","y":390},{"x":"Oct-2017","y":579},{"x":"Nov-2017","y":651},{"x":"Dec-2017","y":832}]

for example :

If I have json as below :

    [{"x":"Aug-2017","y":398},{"x":"Oct-2017","y":579},{"x":"Nov-2017","y":651},{"x":"Dec-2017","y":832}]

result should be :

    [{"x":"Jan-2017","y":0},{"x":"Feb-2017","y":0},{"x":"Mar-2017","y":0},{"x":"Apr-2017","y":0},{"x":"May-2017","y":0},{"x":"Jun-2017","y":0},{"x":"Jul-2017","y":0},{"x":"Aug-2017","y":398},{"x":"Sep-2017","y":0},{"x":"Oct-2017","y":579},{"x":"Nov-2017","y":651},{"x":"Dec-2017","y":832}]

Any help or hint please will really help me out.


Solution

  • You could take an array for the months, sort the given data by year and month and use an index for the data array for maping a whole year until all years are mapped.

    var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        data = [{ x: "Aug-2017", y: 398 }, { x: "Oct-2017", y: 579 }, { x: "Nov-2017", y: 651 }, { x: "Dec-2017", y: 832 }]
            .sort(({ x: a }, { x: b }) => {
                var aa = a.split('-'),
                    bb = b.split('-');
                return aa[1] - bb[1] || months.indexOf(aa[0]) - months.indexOf(bb[0]);
            }),
        index = 0,
        year = data[0].x.slice(-4),
        result = [];
    
    do {
        result.push(...months.map(month =>
            data[index] && data[index].x.slice(0, 3) === month
                ? data[index++]
                : { x: [month, year].join('-'), y: 0 }
        ));
    } while (year++ < data[data.length - 1].x.slice(-4))
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }