I want to create a heatmap depending on the markers for a given year. I start from an array that looks like this:
[{
year: -400;
markers: 3;
},
{
year: -330;
markers: 10;
},
{
year: -20;
markers: 32;
},
...
{
year: 103;
markers: 11;
}
...
]
So how could I fill the array with consecutive years from the beginning (-400) to the current year (2022) with markers at 0?
[{
year: -400;
markers: 3;
},
{
year: -339;
markers: 0;
},
{
year: -338;
markers: 0;
},
...
{
year: -330;
markers: 10;
},
...
{
year: 2021;
markers: 0;
},
{
year: 2022;
markers: 0;
}
]
The point is to get a final array of hex depending on the number of markers of each year to use it on a gradient CSS background.
['#DEDEDE', '#F9DB88', ..., '#DEDEDE'...]
CodePudding user response:
In order not to run through the array thousands of times looking for values, I suggest creating a dictionary:
const arr = [
{
year: -400,
markers: 3,
},
...
];
const dict = Object.fromEntries(arr.map((a) => [a.year, a.markers]));
let result = [];
const currentYear = new Date().getFullYear();
for (let i = -400; i <= currentYear; i ) {
result.push({
year: i,
markers: dict[i] ?? 0,
});
}
CodePudding user response:
Use a for loop and push the unknown values!
const arr = [{
year: -400,
markers: 3,
},
{
year: -330,
markers: 10,
},
{
year: -20,
markers: 32,
},
{
year: 103,
markers: 11,
}
];
let output = [];
const currentYear = (new Date()).getFullYear();
for(let i = -400; i <= currentYear; i ) {
const found = arr.find(x => x.year === i);
if(found) {
output.push(found);
} else {
output.push({
year: i,
markers: 0,
});
}
}
console.log(output);
CodePudding user response:
Try like below. Explanation is in comment.
let data = [{
year: -400,
markers: 3,
},
{
year: -330,
markers: 10,
},
{
year: -20,
markers: 32,
},
{
year: 103,
markers: 11,
}
];
// variable for result array
let result = [];
// loop over years
for (let year = -400; year <= 2022; year ) {
// filter your data and check if marker exist for selected year
let arr = data.filter(d => d.year == year);
// if exists then push that value else add new object with marker = 0
if (arr.length > 0)
result.push(arr[0]);
else
result.push({
year: year,
markers: 0
});
}
console.log(result);
CodePudding user response:
You can first create an placeholder array and then start to replace the values
// start with those years
const start = [{
year: -400,
markers: 3,
},
{
year: -330,
markers: 10,
},
{
year: -20,
markers: 32,
},
{
year: 103,
markers: 11,
}
];
// your first and last year
const firstYear = start[0].year;
const lastYear = start[start.length - 1].year;
// calculate the timespan between the years
const years = lastYear - firstYear;
// build an empty array with markers as 0
const res = Array.from({
length: years
}).map((_, i) => ({
year: firstYear i,
markers: 0
}));
// replace the years that you have a value for
const yearNumbers = res.map(year => year.year);
for (let existing of start) {
const overwrite = yearNumbers.indexOf(existing.year);
if (overwrite === -1) {
break;
}
res[overwrite] = existing;
}
console.log(res)
CodePudding user response:
You might not actually need to fill in your initial array with the missing values. You could do something like this (it's more efficient from a memory point of view and depending on how you use this data, it might be at least ok from a processing time point of view also):
let data = [
{
year: -400,
markers: 3,
},
{
year: -399,
markers: 10,
},
{
year: -396,
markers: 10,
},
];
let availableYears = [];
data.forEach((obj) => availableYears.push(obj.year));
const startYear = data[0].year;
const endYear = data[data.length - 1].year;
for (year = startYear; year <= endYear; year ) {
if (!availableYears.includes(year)) {
/*Here you would use however you want the fact that
you know that the markers for this year are missing.
For the purpose of this example, I just logged the value
you would have inserted in the array with your approach*/
console.log({
year,
markers: 0,
});
}
}
This approach could be a lot more efficient especially for a sparse data
array (one with a lot of missing years).
A stackblitz example: https://stackblitz.com/edit/js-1bsmeh?file=index.js