kr3w4
kr3w4

Reputation: 85

How to group year and reduce object?

I want to update the object to only display the most recent year, only one per year.

The current dividends variable is:

const data = {
    0: [
        'AAPL',
        0.378571,
        '2012-09-30'
    ],
    1: [
        'AAPL',
        0.378571,
        '2012-12-31'
    ],
    2: [
        'AAPL',
        0.378571,
        '2013-03-31'
    ],
    3: [
        'AAPL',
        0.435714,
        '2013-09-30'
    ],
    4: [
        'AAPL',
        0.435714,
        '2013-12-31'
    ],
    5: [
        'AAPL',
        0.47,
        '2014-09-30'
    ],
    6: [
        'AAPL',
        0.47,
        '2014-12-31'
    ],
    7: [
        'AAPL',
        0.52,
        '2015-06-30'
    ],
    8: [
        'AAPL',
        0.52,
        '2015-09-30'
    ],
    9: [
        'AAPL',
        0.52,
        '2015-12-31'
    ]
};

And I would like to update the variable to:

const dividends = {
    0: [
        'AAPL',
        0.378571,
        '2012-12-31'
    ],
    1: [
        'AAPL',
        0.435714,
        '2013-12-31'
    ],
    2: [
        'AAPL',
        0.47,
        '2014-12-31'
    ],
    3: [
        'AAPL',
        0.52,
        '2015-12-31'
    ]
};

Sorry had to remove code block format because stackoverflow won't let me to post due to error

Upvotes: 0

Views: 66

Answers (4)

guest271314
guest271314

Reputation: 1

You can use Object.values() to convert the object to an array, .filter() to check if inverted Boolean of .some() date string element of original array Date object .getFullYear() is equal to current element of iteration, .getMonth() is greater than current element, and .getDate() is greater than or equal to current element, pass resulting array to Object.assign() to set each array as a 0-based property of a JavaScript plain object

const data = {"0":["AAPL",0.378571,"2012-09-30"],"1":["AAPL",0.378571,"2012-12-31"],"2":["AAPL",0.378571,"2013-03-31"],"3":["AAPL",0.435714,"2013-09-30"],"4":["AAPL",0.435714,"2013-12-31"],"5":["AAPL",0.47,"2014-09-30"],"6":["AAPL",0.47,"2014-12-31"],"7":["AAPL",0.52,"2015-06-30"],"8":["AAPL",0.52,"2015-09-30"],"9":["AAPL",0.52,"2015-12-31"]};

const dividends = Object.assign({}, Object.values(data)
                    .filter(([,,d], i, _, a = new Date(d)) => 
                      !_.some(([,,e], i, _, b = new Date(e)) =>
                        b.getFullYear() === a.getFullYear()
                        && b.getMonth() > a.getMonth() 
                        && b.getDate() >= a.getDate()
                        )
                    ));
          
console.log(dividends);

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386660

You could reduce from the right side the sorted data by date and collect for each year and group only one data set.

const
    data = { 0: ['AAPL', 0.378571, '2012-09-30'], 1: ['AAPL', 0.378571, '2012-12-31'], 2: ['AAPL', 0.378571, '2013-03-31'], 3: ['AAPL', 0.435714, '2013-09-30'], 4: ['AAPL', 0.435714, '2013-12-31'], 5: ['AAPL', 0.47, '2014-09-30'], 6: ['AAPL', 0.47, '2014-12-31'], 7: ['AAPL', 0.52, '2015-06-30'], 8: ['AAPL', 0.52, '2015-09-30'], 9: ['AAPL', 0.52, '2015-12-31'] },
    years = {},
    result = Object.assign({}, Object.assign([], data).reduceRight((r, a) => {
        if (!years[a[2].slice(0, 4)] && !r.find(b => [0, 1].every(i => a[i] === b[i]))) {
            r.push(a);
            years[a[2].slice(0, 4)] = true;
        }
        return r;
    }, []).reverse());
   
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 0

Hassan Imam
Hassan Imam

Reputation: 22554

You can use array#reduce to group your data based on year with oldest date in an object. Then get all the values using Object.values().

const data = { 0: [ 'AAPL', 0.378571, '2012-09-30' ], 1: [ 'AAPL', 0.378571, '2012-12-31' ], 2: [ 'AAPL', 0.378571, '2013-03-31' ], 3: [ 'AAPL', 0.435714, '2013-09-30' ], 4: [ 'AAPL', 0.435714, '2013-12-31' ], 5: [ 'AAPL', 0.47, '2014-09-30' ], 6: [ 'AAPL', 0.47, '2014-12-31' ], 7: [ 'AAPL', 0.52, '2015-06-30' ], 8: [ 'AAPL', 0.52, '2015-09-30' ], 9: [ 'AAPL', 0.52, '2015-12-31' ] },
    result = Object.values(data).reduce((r,a) => {
      let year = a[2].substr(0,4);
      r[year] = r[year] || [...a];
      r[year] = r[year][2] > a[2] ? r[year]: [...a];
      return r;
    },{});
const dividends = {...Object.values(result)};
console.log(dividends);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

Kalaiselvan
Kalaiselvan

Reputation: 2134

hope it will be helpful to you..

const data = {
    0: [
        'AAPL',
        0.378571,
        '2012-09-30'
    ],
    1: [
        'AAPL',
        0.378571,
        '2012-12-31'
    ],
    2: [
        'AAPL',
        0.378571,
        '2013-03-31'
    ],
    3: [
        'AAPL',
        0.435714,
        '2013-09-30'
    ],
    4: [
        'AAPL',
        0.435714,
        '2013-12-31'
    ],
    5: [
        'AAPL',
        0.47,
        '2014-09-30'
    ],
    6: [
        'AAPL',
        0.47,
        '2014-12-31'
    ],
    7: [
        'AAPL',
        0.52,
        '2015-06-30'
    ],
    8: [
        'AAPL',
        0.52,
        '2015-09-30'
    ],
    9: [
        'AAPL',
        0.52,
        '2015-12-31'
    ]
};

var years=[];
var result={};
var count=0;
for(var key in data){
  var arr=data[key];
  var year=arr[2].split("-")[0];
  if(years.indexOf(year)==-1){
    years.push(year);
    result[count]=arr;
    count++;
  }  
}
console.log(result);

Upvotes: 0

Related Questions