Take current month range of dates from json response in jquery - javascript

I am developing an application. I am getting a response from the AJAX request like this:
{
"country": "italy",
"timeline": {
"cases": {
"1/22/20": 0,
"1/23/20": 0,
"1/24/20": 0,
"1/25/20": 0,
"1/26/20": 0,
"1/27/20": 0,
"1/28/20": 0,
"1/29/20": 0,
"1/30/20": 0,
"1/31/20": 2,
"2/1/20": 2,
"2/2/20": 2,
"2/3/20": 2,
"2/4/20": 2,
"2/5/20": 2,
"2/6/20": 2,
"2/7/20": 3,
"2/8/20": 3,
"2/9/20": 3,
"2/10/20": 3,
"2/11/20": 3,
"2/12/20": 3,
"2/13/20": 3,
"2/14/20": 3,
"2/15/20": 3,
"2/16/20": 3,
"2/17/20": 3,
"2/18/20": 3,
"2/19/20": 3,
"2/20/20": 3,
"2/21/20": 20,
"2/22/20": 62,
"2/23/20": 155,
"2/24/20": 229,
"2/25/20": 322,
"2/26/20": 453,
"2/27/20": 655,
"2/28/20": 888,
"2/29/20": 1128,
"3/1/20": 1694,
"3/2/20": 2036,
"3/3/20": 2502,
"3/4/20": 3089,
"3/5/20": 3858,
"3/6/20": 4636,
"3/7/20": 5883,
"3/8/20": 7375,
"3/9/20": 9172,
"3/10/20": 10149,
"3/11/20": 12462,
"3/12/20": 12462,
"3/13/20": 17660,
"3/14/20": 21157,
"3/15/20": 24747,
"3/16/20": 27980,
"3/17/20": 31506,
"3/18/20": 35713,
"3/19/20": 41035,
"3/20/20": 47021,
"3/21/20": 53578,
"3/22/20": 59138,
"3/23/20": 63927,
"3/24/20": 69176,
"3/25/20": 74386,
"3/26/20": 80589,
"3/27/20": 86498
},
"deaths": {
"1/22/20": 0,
"1/23/20": 0,
"1/24/20": 0,
"1/25/20": 0,
"1/26/20": 0,
"1/27/20": 0,
"1/28/20": 0,
"1/29/20": 0,
"1/30/20": 0,
"1/31/20": 0,
"2/1/20": 0,
"2/2/20": 0,
"2/3/20": 0,
"2/4/20": 0,
"2/5/20": 0,
"2/6/20": 0,
"2/7/20": 0,
"2/8/20": 0,
"2/9/20": 0,
"2/10/20": 0,
"2/11/20": 0,
"2/12/20": 0,
"2/13/20": 0,
"2/14/20": 0,
"2/15/20": 0,
"2/16/20": 0,
"2/17/20": 0,
"2/18/20": 0,
"2/19/20": 0,
"2/20/20": 0,
"2/21/20": 1,
"2/22/20": 2,
"2/23/20": 3,
"2/24/20": 7,
"2/25/20": 10,
"2/26/20": 12,
"2/27/20": 17,
"2/28/20": 21,
"2/29/20": 29,
"3/1/20": 34,
"3/2/20": 52,
"3/3/20": 79,
"3/4/20": 107,
"3/5/20": 148,
"3/6/20": 197,
"3/7/20": 233,
"3/8/20": 366,
"3/9/20": 463,
"3/10/20": 631,
"3/11/20": 827,
"3/12/20": 827,
"3/13/20": 1266,
"3/14/20": 1441,
"3/15/20": 1809,
"3/16/20": 2158,
"3/17/20": 2503,
"3/18/20": 2978,
"3/19/20": 3405,
"3/20/20": 4032,
"3/21/20": 4825,
"3/22/20": 5476,
"3/23/20": 6077,
"3/24/20": 6820,
"3/25/20": 7503,
"3/26/20": 8215,
"3/27/20": 9134
}
}
}
As you can, I have dates for the month of February and March in this response. I want to get only the range of dates with the corresponding value within the current month, that is March in this case. How can I achieve this in jQuery?
$.ajax({
url: 'https://corona.lmao.ninja/v2/historical/italy',
type: 'GET',
dataType: 'JSON',
success: function(data) {
console.log('in');
console.log(data);
}
});

You may use Object.keys(), filter() & reduce() methods to acheive this like:
$.ajax({
url: 'https://corona.lmao.ninja/v2/historical/italy',
type: 'GET',
dataType: 'JSON',
success: function(data) {
const date = new Date(),y = date.getFullYear(),m = date.getMonth();
const firstDay = new Date(y, m, 1).getTime(), lastDay = new Date(y, m + 1, 0).getTime();
const currentData = Object.keys(data.timeline.cases)
.filter(key => firstDay <= new Date(key).getTime() && new Date(key).getTime() <= lastDay)
.reduce((o, k) => { o[k] = data.timeline.cases[k]; return o }, {});
console.log(currentData)
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Explanation:
First inside ajax success method, we are trying to get first & last day of the current month, as we need those values to filter data.
Then using Object.keys we get all the keys in data.timeline.cases as this holds all the date strings as key.
Then using filter() method we get only the keys which are between first and last day of the current month.
Then using reduce() method we are trying to reconstruct the data.timeline.cases object back, so that you can use it in your application.

To achieve this you can use $.each() to determine whether the key in the cases object is a date within the current month and use it to create a new object with those entities. Try this:
$.ajax({
url: 'https://corona.lmao.ninja/v2/historical/italy',
type: 'GET',
dataType: 'JSON',
success: function(data) {
var currentMonth = new Date().getMonth();
var currentMonthCases = {};
$.each(data.timeline.cases, (k, v) => {
if (new Date(k).getMonth() === currentMonth)
currentMonthCases[k] = v;
})
console.log(currentMonthCases);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Using map, reduce, you can do is very easly. I have written a parser, will give you more stats. Please check.
const data = {
country: "italy",
timeline: {
cases: {
"1/22/20": 0,
"1/23/20": 0,
"1/24/20": 0,
"1/25/20": 0,
"1/26/20": 0,
"1/27/20": 0,
"1/28/20": 0,
"1/29/20": 0,
"1/30/20": 0,
"1/31/20": 2,
"2/1/20": 2,
"2/2/20": 2,
"2/3/20": 2,
"2/4/20": 2,
"2/5/20": 2,
"2/6/20": 2,
"2/7/20": 3,
"2/8/20": 3,
"2/9/20": 3,
"2/10/20": 3,
"2/11/20": 3,
"2/12/20": 3,
"2/13/20": 3,
"2/14/20": 3,
"2/15/20": 3,
"2/16/20": 3,
"2/17/20": 3,
"2/18/20": 3,
"2/19/20": 3,
"2/20/20": 3,
"2/21/20": 20,
"2/22/20": 62,
"2/23/20": 155,
"2/24/20": 229,
"2/25/20": 322,
"2/26/20": 453,
"2/27/20": 655,
"2/28/20": 888,
"2/29/20": 1128,
"3/1/20": 1694,
"3/2/20": 2036,
"3/3/20": 2502,
"3/4/20": 3089,
"3/5/20": 3858,
"3/6/20": 4636,
"3/7/20": 5883,
"3/8/20": 7375,
"3/9/20": 9172,
"3/10/20": 10149,
"3/11/20": 12462,
"3/12/20": 12462,
"3/13/20": 17660,
"3/14/20": 21157,
"3/15/20": 24747,
"3/16/20": 27980,
"3/17/20": 31506,
"3/18/20": 35713,
"3/19/20": 41035,
"3/20/20": 47021,
"3/21/20": 53578,
"3/22/20": 59138,
"3/23/20": 63927,
"3/24/20": 69176,
"3/25/20": 74386,
"3/26/20": 80589,
"3/27/20": 86498
},
deaths: {
"1/22/20": 0,
"1/23/20": 0,
"1/24/20": 0,
"1/25/20": 0,
"1/26/20": 0,
"1/27/20": 0,
"1/28/20": 0,
"1/29/20": 0,
"1/30/20": 0,
"1/31/20": 0,
"2/1/20": 0,
"2/2/20": 0,
"2/3/20": 0,
"2/4/20": 0,
"2/5/20": 0,
"2/6/20": 0,
"2/7/20": 0,
"2/8/20": 0,
"2/9/20": 0,
"2/10/20": 0,
"2/11/20": 0,
"2/12/20": 0,
"2/13/20": 0,
"2/14/20": 0,
"2/15/20": 0,
"2/16/20": 0,
"2/17/20": 0,
"2/18/20": 0,
"2/19/20": 0,
"2/20/20": 0,
"2/21/20": 1,
"2/22/20": 2,
"2/23/20": 3,
"2/24/20": 7,
"2/25/20": 10,
"2/26/20": 12,
"2/27/20": 17,
"2/28/20": 21,
"2/29/20": 29,
"3/1/20": 34,
"3/2/20": 52,
"3/3/20": 79,
"3/4/20": 107,
"3/5/20": 148,
"3/6/20": 197,
"3/7/20": 233,
"3/8/20": 366,
"3/9/20": 463,
"3/10/20": 631,
"3/11/20": 827,
"3/12/20": 827,
"3/13/20": 1266,
"3/14/20": 1441,
"3/15/20": 1809,
"3/16/20": 2158,
"3/17/20": 2503,
"3/18/20": 2978,
"3/19/20": 3405,
"3/20/20": 4032,
"3/21/20": 4825,
"3/22/20": 5476,
"3/23/20": 6077,
"3/24/20": 6820,
"3/25/20": 7503,
"3/26/20": 8215,
"3/27/20": 9134
}
}
};
const parseDate = srt => {
const [m, d, y] = srt.split("/");
return new Date(d, m - 1, y).getMonth();
};
const toArray = obj => {
const generator = function*() {
for (let key in obj) {
yield [obj[key], key];
}
};
return {
[Symbol.iterator]: generator,
map: function(fn) {
let result = [];
for (let [value, key] of this) {
result.push(fn(value, key));
}
return result;
}
};
};
const grouped = toArray(data.timeline.cases)
.map((x, k) => [x, k])
.reduce((m, c) => {
const parsedDate = parseDate(c[1]);
if (!m[parsedDate]) {
m[parsedDate] = { cases: [], deaths: [], totalCases: 0, totalDeaths: 0 };
}
m[parsedDate].cases.push({ date: c[1], cases: c[0] });
m[parsedDate].deaths.push({
date: c[1],
deaths: data.timeline.deaths[c[1]]
});
m[parsedDate].totalCases += c[0];
m[parsedDate].totalDeaths += data.timeline.deaths[c[1]];
return m;
}, {});
// console.log(JSON.stringify(grouped, null, 2));
// For march
console.log(JSON.stringify(grouped[2], null, 2));
console.log(grouped[2].totalDeaths);
console.log(grouped[2].totalCases);
// For feb
console.log(JSON.stringify(grouped[1], null, 2));
console.log(grouped[1].totalDeaths);
console.log(grouped[1].totalCases);

Related

Is there a way to make math calculations with two objects with the same keys efficiently?

I'm currently working on a Tennis scorer where the user inputs the information for each point and then gets saved in an object. The way I do this is whenever a set ends, a new object is created inside a global object with the information of the match at that moment, so the information for each set is cumulative. An example of a match would look like this:
"sets": {
"set1": {
"equipo1": {
"breakPoints": 5,
"breakPointsExito": 0,
"games": 5,
"jugador1": {
"smashes": 0,
"smashesExito": 5,
"unfError": 0,
"winners": 0,
},
"jugador2": {
"smashes": 0,
"smashesExito": 1,
"unfError": 0,
"winners": 2,
},
"puntosOro": 0,
},
"equipo2": {
"breakPoints": 3,
"breakPointsExito": 1,
"games": 7,
"jugador1": Object {
"smashes": 0,
"smashesExito": 5,
"unfError": 0,
"winners": 2,
},
"jugador2": {
"smashes": 0,
"smashesExito": 2,
"unfError": 0,
"winners": 3,
},
"puntosOro": 2,
},
},
"set2": {
"equipo1": {
"breakPoints": 8,
"breakPointsExito": 1,
"games": 2,
"jugador1": Object {
"smashes": 0,
"smashesExito": 8,
"unfError": 0,
"winners": 2,
},
"jugador2": {
"smashes": 0,
"smashesExito": 3,
"unfError": 0,
"winners": 3,
},
"puntosOro": 1,
},
"equipo2": {
"breakPoints": 4,
"breakPointsExito": 2,
"games": 2,
"jugador1": Object {
"smashes": 0,
"smashesExito": 9,
"unfError": 0,
"winners": 2,
},
"jugador2": {
"smashes": 0,
"smashesExito": 5,
"unfError": 0,
"winners": 8,
},
"puntosOro": 2,
},
},
}
Now, what I want to do is to show this information by sets, so, let's say we wanted to show the information of the 3rd set, we would have to subtract the sum of the previous sets. I was wondering if there was any way to make this efficiently since the keys of each set object are essentially the same, with only the value changing.
Right now I made it work by creating an object based on the sets results, but it's very ugly and I hope there's a way of better doing this:
if (value == 0) {
matchFunc([
{
name: "Break Points",
equipo1: infoEquipo1.breakPointsExito,
equipo2: infoEquipo2.breakPointsExito,
},
{
name: "Puntos de Oro",
equipo1: infoEquipo1.puntosOro,
equipo2: infoEquipo2.puntosOro,
},
{
name: "Winners",
equipo1:
infoMatchEquipo1.jugador1.winners +
infoMatchEquipo1.jugador2.winners,
equipo2:
infoMatchEquipo2.jugador1.winners +
infoMatchEquipo2.jugador2.winners,
},
{
name: "Smashes",
equipo1:
infoMatchEquipo1.jugador1.smashesExito +
infoMatchEquipo1.jugador2.smashesExito,
equipo2:
infoMatchEquipo2.jugador1.smashesExito +
infoMatchEquipo2.jugador2.smashesExito,
},
{
name: "Unforced Errors",
equipo1:
infoMatchEquipo1.jugador1.unfError +
infoMatchEquipo1.jugador2.unfError,
equipo2:
infoMatchEquipo2.jugador1.unfError +
infoMatchEquipo2.jugador2.unfError,
},
]);
}
if (value == 1) {
matchFunc([
{
name: "Winners",
equipo1:
infoSets.set1.equipo1.jugador1.winners +
infoSets.set1.equipo1.jugador2.winners,
equipo2:
infoSets.set1.equipo2.jugador1.winners +
infoSets.set1.equipo2.jugador2.winners,
},
{
name: "Smashes",
equipo1:
infoSets.set1.equipo1.jugador1.smashesExito +
infoSets.set1.equipo1.jugador2.smashesExito,
equipo2:
infoSets.set1.equipo2.jugador1.smashesExito +
infoSets.set1.equipo2.jugador2.smashesExito,
},
{
name: "Unforced Errors",
equipo1:
infoSets.set1.equipo1.jugador1.unfError +
infoSets.set1.equipo1.jugador2.unfError,
equipo2:
infoSets.set1.equipo2.jugador1.unfError +
infoSets.set1.equipo2.jugador2.unfError,
},
]);
}
if (value == 2) {
matchFunc([
{
name: "Winners",
equipo1:
infoSets.set2.equipo1.jugador1.winners +
infoSets.set2.equipo1.jugador2.winners -
(infoSets.set1.equipo1.jugador1.winners +
infoSets.set1.equipo1.jugador2.winners),
equipo2:
infoSets.set2.equipo2.jugador1.winners +
infoSets.set2.equipo2.jugador2.winners -
(infoSets.set1.equipo2.jugador1.winners +
infoSets.set1.equipo2.jugador2.winners),
},
{
name: "Smashes",
equipo1:
infoSets.set2.equipo1.jugador1.smashesExito +
infoSets.set2.equipo1.jugador2.smashesExito -
(infoSets.set1.equipo1.jugador1.smashesExito +
infoSets.set1.equipo1.jugador2.smashesExito),
equipo2:
infoSets.set2.equipo2.jugador1.smashesExito +
infoSets.set2.equipo2.jugador2.smashesExito -
(infoSets.set1.equipo2.jugador1.smashesExito +
infoSets.set1.equipo2.jugador2.smashesExito),
},
{
name: "Unforced Errors",
equipo1:
infoSets.set2.equipo1.jugador1.unfError +
infoSets.set2.equipo1.jugador2.unfError -
(infoSets.set1.equipo1.jugador1.unfError +
infoSets.set1.equipo1.jugador2.unfError),
equipo2:
infoSets.set2.equipo2.jugador1.unfError +
infoSets.set2.equipo2.jugador2.unfError -
(infoSets.set1.equipo2.jugador1.unfError +
infoSets.set1.equipo2.jugador2.unfError),
},
]);
}
I'm sorry, I know that this looks horrendous, but it's the only way i've been able to make it work. The if(value) refers to the sets, and the 0 is for the entire match.

loopin throug object and array using hasOwnProperty

i have this object:
obj = {23-10-2022: 3, 24-10-2022: 1, 28-10-2022: 4, 29-10-2022: 1, 30-10-2022: 1}
and this dates array:
dates = [19-10-2022, 20-10-2022, 21-10-2022, 22-10-2022, 23-10-2022, 24-10-2022, 25-10-2022, 26-10-2022, 27-10-2022, 28-10-2022, 29-10-2022, 30-10-2022, 31-10-2022]
i want to loop throug the obj and array and to check:
if the first key in the obj === dates[i] so return obj[key]=(the value) and move to the next obj key but continue from the next dates[i] and not from the begginnig elese return the 0.
at the end i want to get in return: 0,0,0,0,3,1,0,0,0,4,1,1
here is my code:
for (let key in obj){
for (let i = 0; i < dates.length; i++){
if (obj.hasOwnProperty(key)) {
let value = obj[key];
let date = dates[i];
return key
if(key===date){
return value;
key++ ///gives NaN not correct
}
else{
return 0;
}
}
}
}
what i need to change?
at the moment it return:
[0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4]
becuse it gets back to the firt dates value and re-check.
You can just map() over the dates array. Here using the nullish coalescing operator (??) to assign 0 if retrieving the property returns undefined.
const obj = { '23-10-2022': 3, '24-10-2022': 1, '28-10-2022': 4, '29-10-2022': 1, '30-10-2022': 1 }
const dates = ['19-10-2022', '20-10-2022', '21-10-2022', '22-10-2022', '23-10-2022', '24-10-2022', '25-10-2022', '26-10-2022', '27-10-2022', '28-10-2022', '29-10-2022', '30-10-2022', '31-10-2022']
const result = dates.map(date => obj[date] ?? 0);
console.log(result)

Javascript how to use reduce to get sum of an attribute's value from nested objects?

I have an object like the following:
data_sample = {
"object_1": {
"irrelevant_data1": 0,
"irrelevant_data2": 0,
"data_needed_to_sum_up": 100,
},
"object_a": {
"irrelevant_data1": 0,
"irrelevant_data2": 0,
"irrelevant_data3": 0,
"data_needed_to_sum_up": 200,
},
"object_d": {
"irrelevant_data1": 0,
"irrelevant_data2": 0,
"data_needed_to_sum_up": 300,
},
}
How can I use the reduce method to get the sum of all data_needed_to_sum_up inside data_sample to get the expected result of 600?
You could use Object.valuesto and then use reduce
data_sample = { "object_1": { "irrelevant_data1": 0, "irrelevant_data2": 0, "data_needed_to_sum_up": 100, }, "object_a": { "irrelevant_data1": 0, "irrelevant_data2": 0, "irrelevant_data3": 0, "data_needed_to_sum_up": 200, }, "object_d": { "irrelevant_data1": 0, "irrelevant_data2": 0, "data_needed_to_sum_up": 300, }, }
res = Object.values(data_sample)
.reduce((acc,curr) => acc = acc + curr["data_needed_to_sum_up"],0)
console.log(res)
.reduce works on arrays, what you have is just an object, but you could use .reduce in conjunction with Object.entries, like so:
data_sample = {
"object_1": {
"irrelevant_data1": 0,
"irrelevant_data2": 0,
"data_needed_to_sum_up": 100,
},
"object_a": {
"irrelevant_data1": 0,
"irrelevant_data2": 0,
"irrelevant_data3": 0,
"data_needed_to_sum_up": 200,
},
"object_d": {
"irrelevant_data1": 0,
"irrelevant_data2": 0,
"data_needed_to_sum_up": 300,
},
}
console.log(Object.entries(data_sample).reduce((carry, [_, current]) => carry + current.data_needed_to_sum_up, 0))
You can use Array#reduce on Object.values.
let sum = Object.values(data_sample)
.reduce((acc,cur)=>acc+cur.data_needed_to_sum_up,0);
Try this:
console.log(Object.values(data_sample).map((x) => x.data_needed_to_sum_up).reduce((x, y) => x + y));
use Object.valuesto first then use reduce

How to avoid variable scope issues within a map function?

I have a working solution of this problem but I'm trying to make a cleaner and neat version of it as much as possible. I came up with another solution that uses a function within a map function. Unfortunately, this version has a few issues and I want to just know why the second solution is not working. I'm guessing it's a variable scope issue here. I'm looking forward to know your opinion about it.
I have a simple function that prints calendar days in an array!
So a question is why the first version of my code get the expected results while the second version prints unexpected results.
I tried to change let to var and I also made the counter and startedIndexing outside the function scope.
Solution 1 (works):
const currentFullMonth = {
days_length: 31,
first_day: "Thu",
first_day_index: 4,
last_day: "Sat",
last_day_index: 6,
month: "Aug",
year: 2019
}
const testMonth = [
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0]
];
function printMonthCalender(month) {
let counter = 0;
let startedIdxing = false;
return month.map(week => {
return week.map((day, index) => {
if (index === currentFullMonth.first_day_index && !startedIdxing) {
counter++;
startedIdxing = true;
return counter;
} else if (startedIdxing) {
if (currentFullMonth.days_length === counter) {
counter = 0;
}
counter++;
return counter;
} else {
return 0;
}
});
});
} // end of Solution #1 <-- this works :)
Solution 2 (doesn't work):
// start of Solution #2 <-- does not work :(
// im using two functions to make it look more cleaner
//
function printMonthCalender2(month) {
let counter = 0;
let startedIdxing = false;
return month.map(week => {
return week.map((day, index) =>
indexingMonth(counter, startedIdxing, index)
);
});
}
function indexingMonth(counter, startedIdxing, index) {
if (index === currentFullMonth.first_day_index && !startedIdxing) {
counter++;
startedIdxing = true;
return counter;
} else if (startedIdxing) {
if (currentFullMonth.days_length === counter) {
counter = 0;
}
counter++;
return counter;
} else {
return 0;
}
}// end of Solution #2
console.log(printMonthCalender(testMonth));
console.log(printMonthCalender2(testMonth));
expected result as follows (first version):
[0, 0, 0, 0, 1, 2, 3]
[4, 5, 6, 7, 8, 9, 10]
[11, 12, 13, 14, 15, 16, 17]
[18, 19, 20, 21, 22, 23, 24]
[25, 26, 27, 28, 29, 30, 31]
[1, 2, 3, 4, 5, 6, 7]
unexpected result as follows (second version):
[0, 0, 0, 0, 1, 0, 0]
[0, 0, 0, 0, 1, 0, 0]
[0, 0, 0, 0, 1, 0, 0]
[0, 0, 0, 0, 1, 0, 0]
[0, 0, 0, 0, 1, 0, 0]
[0, 0, 0, 0, 1, 0, 0]
The problem is that when you reassign startedIdxing inside of indexingMonth, it's a local variable, so it doesn't get changed inside of the calling function (printMonthCalender2).
An issue is that .map should not have mutation or reassignment as a side-effect. While you could tweak things so that indexingMonth returned something that you checked and then reassigned startedIdxing to, I'd prefer a different approach: create a flat array, eg
[0, 0, 0, 0, 1, 2, ..., 30, 31, 1, 2, 3]
and then chunk it into pieces of 7 afterwards:
const currentFullMonth = {
days_length: 31,
first_day: "Thu",
first_day_index: 4,
last_day: "Sat",
last_day_index: 6,
month: "Aug",
year: 2019
}
const makeZeroArr = length => new Array(length).fill(0);
const printMonthCalendar = (testMonth) => {
// Create array: [1, 2, 3, ..., 30, 31]
const oneMonth = Array.from(
{ length: currentFullMonth.days_length },
(_, i) => i + 1
);
// Create a flat array with leading zeros and trailing last week:
// [0, 0, 0, 0, 1, 2, 3, ..., 30, 31, 1, 2, 3, 4, 5, 6, 7]
const flatResultArr = [
...makeZeroArr(currentFullMonth.first_day_index),
...oneMonth,
...oneMonth // this includes extra numbers that will be trimmed
].slice(0, 7 * 6); // 7 days/week * 6 weeks
// Chunk the flat array into slices of 7:
const resultArr = [];
for (let i = 0; i < 7; i++) {
resultArr.push(flatResultArr.slice(i * 7, (i + 1) * 7));
}
return resultArr;
};
console.log(printMonthCalendar());
In functions, primitive types like numbers and booleans are passed by value, not by reference. So when you define counter and startedIdxing in printMonthCalender2 and then try to change them in indexingMonth, the changes get lost as soon as you return to printMonthCalender2.
However in JavaScript, objects get passed by reference. So something like this would work:
function printMonthCalender2(month) {
let obj = { counter: 0, startedIdxing = false };
return month.map(week => {
return week.map((day, index) =>
indexingMonth(obj, index)
);
});
}
function indexingMonth(obj, index) {
if (index === currentFullMonth.first_day_index && !obj.startedIdxing) {
obj.counter++;
obj.startedIdxing = true;
return obj.counter;
} else if (obj.startedIdxing) {
if (currentFullMonth.days_length === obj.counter) {
obj.counter = 0;
}
obj.counter++;
return obj.counter;
} else {
return 0;
}
}// end of Solution #2
Things like obj.counter++ will actually keep those changes in your original object defined in printMonthCalender2.
Warning: While you can do this, if you are working with complex code this is often frowned upon. These kinds of mutations can be very difficult to debug if a problem occurs. It's a legitimate programming technique, but shouldn't be abused.
Also if you're working in a team that adheres to the functional programming paradigm, I believe this is a big no-no.
However given the very short duration and limited scope of the obj variable in this example, I would personally feel very comfortable with this. If obj had a much longer lifetime and was used in numerous places in the code then I'd be more wary of it, and would agree with #CertainPerformance's comment that a map statement shouldn't mutate things.

How to create JSON or Array of Objects From Three JS Arrays

How to load into/generate a JSON object or an Array of Objects like below
var players = [
{"name":"John", "startPoint":"3", "maxPoint":"80"},
{"name":"Anna", "startPoint":"6", "maxPoint":"28"},
{"name":"Peter", "startPoint":"6", "maxPoint":"80"},
{"name":"Zack", "startPoint":"2", "maxPoint":"65"},
{"name":"Andy", "startPoint":"4", "maxPoint":"80"},
{"name":"Mick", "startPoint":"0", "maxPoint":"65"},
{"name":"Robin", "startPoint":"2", "maxPoint":"80"},
{"name":"Ed", "startPoint":"5", "maxPoint":"28"},
{"name":"Chris", "startPoint":"1", "maxPoint":"65"},
{"name":"Lee", "startPoint":"3", "maxPoint":"80"},
{"name":"Baron", "startPoint":"6", "maxPoint":"65"},
{"name":"Sam", "startPoint":"1", "maxPoint":"80"}
];
from three JavaScript Array Object as:
var members = ["John","Anna","Peter","Zack","Andy","Mick","Robin","Ed","Chris","Lee","Baron" ,"Sam" ]
var startPoint = [3, 6, 6, 2, 4, 0, 2, 5, 1, 3, 6, 1];
var maxPoint =[80, 28, 80, 65, 80, 65, 80, 80, 65, 80, 65, 80];
var result = [], i;
for (i = 0; i < members.length; ++i) {
result.push({name: members[i], startPoint: startPoint[i], maxPoint: maxPoint[i]});
}
return JSON.stringify(result);

Categories