JavaScript adding zero for non existing keys in array

Viewed 134

I have two arrays:

date_array = ["2020-02-27", "2020-02-28", "2020-02-29", "2020-03-01", "2020-03-02", "2020-03-03", "2020-03-04", "2020-03-05", "2020-03-06", "2020-03-07", "2020-03-08", "2020-03-09", "2020-03-10", "2020-03-11", "2020-03-12", "2020-03-13", "2020-03-14", "2020-03-15", "2020-03-16", "2020-03-17", "2020-03-18", "2020-03-19", "2020-03-20", "2020-03-21", "2020-03-22", "2020-03-23", "2020-03-24", "2020-03-25", "2020-03-26", "2020-03-27"]

and

count_array=[{date: "2020-03-22", count: 310},
 {date: "2020-03-23", count: 115},
 {date: "2020-03-24", count: 78},
 {date: "2020-03-25", count: 29},
 {date: "2020-03-26", count: 36},
 {date: "2020-03-27", count: 3}]

I need to create a third array with 30 elements having only the values of count, if a count is not present for that day, it returns 0. How do I achieve this?

I tried:

date_array.forEach(element => {
                if (
                  data[date_array.indexOf(element)].date ==
                  date_array[element]
                ) {
                  target_array.push(data[data.indexOf(element)].count_array);
                } else {
                  target_array.push(0);
                }
            });

But I'm getting "Cannot read property 'date' of undefined"

2 Answers

To reduce the computational complexity, first transform the array into an object indexed by date. Then, to make the output array, just .map the date_array by looking up the date on the object, alternating with 0:

date_array = ["2020-02-27", "2020-02-28", "2020-02-29", "2020-03-01", "2020-03-02", "2020-03-03", "2020-03-04", "2020-03-05", "2020-03-06", "2020-03-07", "2020-03-08", "2020-03-09", "2020-03-10", "2020-03-11", "2020-03-12", "2020-03-13", "2020-03-14", "2020-03-15", "2020-03-16", "2020-03-17", "2020-03-18", "2020-03-19", "2020-03-20", "2020-03-21", "2020-03-22", "2020-03-23", "2020-03-24", "2020-03-25", "2020-03-26", "2020-03-27"]
count_array=[{date: "2020-03-22", count: 310},
 {date: "2020-03-23", count: 115},
 {date: "2020-03-24", count: 78},
 {date: "2020-03-25", count: 29},
 {date: "2020-03-26", count: 36},
 {date: "2020-03-27", count: 3}]

const countsByDate = Object.fromEntries(
  count_array.map(({ date, count }) => [date, count])
);
const output = date_array.map(date => countsByDate[date] || 0);
console.log(output);

I would go for the solution posted by @CertainPerformance, however just to provide an alternative, in modern javascript (Babel, and new version of modern browsers), it's possible having something like:

var count = date_array.map(date => 
              count_array.find(item => item.date === date)?.count ?? 0);

See find's array method, optional chaining and nullish coalescing operators.

Also, it's not very optimized since find is looking in the whole array for each map's iteration (and that's why I would go for the other answer), but for a small array it's negligible.

Related