Reputation: 732
For example , I have an array of objects like so :
[
{
"waterfallData.PopulationName":"Population 1",
"Deaths":-2333,
"Births":8786,
"open":0,
"close":6453
},
{
"waterfallData.PopulationName":"Population 2",
"Deaths":-1000,
"Births":5000,
"open":0,
"close":10453
},
{
"waterfallData.PopulationName":"Population 3",
"Deaths":-2000,
"Births":500,
"open":0,
"close":8953
}
]
I want to add two(does not have to be two,if there is a "Extra Births"
then three) intermerdiate objects between each population like so
[
{
"waterfallData.PopulationName":"Population 1",
"Death":-2333,
"Births":8786,
"open":0,
"close":6453
},
{
"Deaths" : -1000,
"open" : 6453,
"close" : 5453
},
{
"Births" : 5000,
"open" : 5453,
"close : 10453
}
{
"waterfallData.PopulationName":"Population 2",
"Deaths":-1000,
"Births":5000,
"open":0,
"close":10453
},
{
"Deaths" : -2000,
"open" : 10453,
"close" : 8453
},
{
"Births" : 500,
"open" : 8453,
"close" : 8953
}
{
"waterfallData.PopulationName":"Population 3",
"Deaths":-2000,
"Births":500,
"open":0,
"close":8953
}
]
So as you can see I want to add objects based on the number of properties other than the waterfallData.PopulationName
,open
and close
properties. Then, I want to assign open
and close
properties on each object based on the next "Deaths"
and "Births"
values.
For example , Population 1
starts with 6453 then I add two objects with the 1st object taking the next "Deaths"
value in Population 2
which is -1000 then I assign the open
property to be from the previous close
property of Population 1
and the close
property to be calculated by adding the assigned open
property to "Deaths"
's value. And same goes with the 2nd extra object where I assign the open
property to be the close
property of the previous object and the close
property to be calculated by adding open
with "Births"
's value.
How do I achieve this?
Upvotes: 2
Views: 86
Reputation: 2925
Crude.. but works
var newArr = [];
$x = [{
"waterfallData.PopulationName":"Population 1",
"Deaths":-2333,
"Births":8786,
"open":0,
"close":6453
},{
"waterfallData.PopulationName":"Population 2",
"Deaths":-1000,
"Births":5000,
"open":0,
"close":10453
},{
"waterfallData.PopulationName":"Population 3",
"Deaths":-2000,
"Births":500,
"open":0,
"close":8953
}];
$x.forEach((p,i)=>{
var current = $x[i]
newArr.push(current)
try {
var next = $x[i+1];
var start = current.open;
var end = current.close;
var states = Object.keys(current).sort().filter((k)=>{return (['waterfallData.PopulationName','open','close'].indexOf(k) < 0)})
for (var i=0;i<states.length;i++){
var state = states[i]
var tempObj = {}
tempObj[states[i]] = next[states[i]]
tempObj['open'] = end;
end += next[states[i]];
tempObj['close'] = end;
newArr.push(tempObj)
}
} catch (e) {
return false;
}
})
The code will look for all properties other than waterfallData.Popu..,open,close and treats them as states. If you have 10 properties, there will be 7 states excluding the above 3. Then the open and close values of these states are then calculated from the next element and pushed to new array newArr.
Upvotes: 1
Reputation: 39250
I'll give it a try, you can specify what keys you need to be extra data but the original data must have values for those keys. It'll create the extra items in the order that the keys are provided:
const data = [{"waterfallData.PopulationName":"Population 1","Deaths":-2333,"Births":8786,"open":0,"close":6453},{"waterfallData.PopulationName":"Population 2","Deaths":-1000,"Births":5000,"open":0,"close":10453},{"waterfallData.PopulationName":"Population 3","Deaths":-2000,"Births":500,"open":0,"close":8953}];
const zip = (arr1, arr2) =>
[...new Array(Math.max(arr1.length, arr2.length))]
.map((_, i) => i)
.map((i) => [arr1[i], arr2[i]]);
const extras = (keys) => ([current, next]) =>
keys.map((key) => [key, next[key]]).reduce(
([result, lastClose], [key, nextValue]) => [
result.concat({
[key]: nextValue,
open: lastClose,
close: nextValue + lastClose,
}),
nextValue + lastClose,
],
[[], current.close],
)[0];
const withExtras = (keys) => ([current, next]) =>
!next
? [current]
: [current].concat(extras(keys)([current, next]));
console.log(
zip(data, data.slice(1)) //having [[current,next],[current,next]...]
.map(withExtras(['Deaths', 'Births']))
.flatten(),
);
console.log(
'diffenrent order different result',
zip(data, data.slice(1))
.map(withExtras(['Births', 'Deaths']))
.flatten(),
);
Upvotes: 0