Reputation: 658
I am currently using a for loop and multiple if statements to count the number of records that match a string.
for (var i = 0; i < DailyLogs.length; i++) {
if (DailyLogs[i].created_at >= this.state.startMonth && DailyLogs[i].created_at <= this.state.finishMonth) {
if (DailyLogs[i].created_by_id === "37aa0778-c148-4c04-b239-18885d46a8b0" ) { md1++; }
if (DailyLogs[i].created_by_id === "869a7967-ffb3-4a20-b402-ad6d514472de" ) { md2++; }
if (DailyLogs[i].created_by_id === "92c0f155-ce82-4b50-821f-439428c517a3" ) { md3++; }
if (DailyLogs[i].created_by_id === "aa9eb0f2-35af-469a-8893-fc777b444bed" ) { md4++; }
if (DailyLogs[i].created_by_id === "967d63ea-492c-4475-8b08-911be2d0bf22" ) { md5++; }
if (DailyLogs[i].created_by_id === "47ec8d60-1fa2-4bf5-abc8-34df6bd53079" ) { md6++; }
if (DailyLogs[i].created_by_id === "92c0f155-ce82-4b50-821f-439428c517a3" ) { md7++; }
}
}
Is there a better way to do this, apart from having multiple if statements, or perhaps shorting this somehow.
Upvotes: 1
Views: 74
Reputation: 1074495
You can make it (slightly) more efficient by using else if
, since if an earlier if
's condition is true, by definition later ones can't be.
Long series of else if
in JavaScript can be written as switch
instead.
for (var i = 0; i < DailyLogs.length; i++) {
if (DailyLogs[i].created_at >= this.state.startMonth && DailyLogs[i].created_at <= this.state.finishMonth) {
switch (DailyLogs[i].created_by_id) {
case "37aa0778-c148-4c04-b239-18885d46a8b0": md1++; break;
case "869a7967-ffb3-4a20-b402-ad6d514472de": md2++; break;
case "92c0f155-ce82-4b50-821f-439428c517a3": md3++; break;
case "aa9eb0f2-35af-469a-8893-fc777b444bed": md4++; break;
case "967d63ea-492c-4475-8b08-911be2d0bf22": md5++; break;
case "47ec8d60-1fa2-4bf5-abc8-34df6bd53079": md6++; break;
case "92c0f155-ce82-4b50-821f-439428c517a3": md7++; break;
}
}
}
Using else if
vs. switch
is largely a matter of style in cases like this.
Another option is to maintain your counters in an object keyed by the created_by_id
:
var md = {
"37aa0778-c148-4c04-b239-18885d46a8b0": 0,
"869a7967-ffb3-4a20-b402-ad6d514472de": 0,
"92c0f155-ce82-4b50-821f-439428c517a3": 0,
"aa9eb0f2-35af-469a-8893-fc777b444bed": 0,
"967d63ea-492c-4475-8b08-911be2d0bf22": 0,
"47ec8d60-1fa2-4bf5-abc8-34df6bd53079": 0,
"92c0f155-ce82-4b50-821f-439428c517a3": 0
};
for (var i = 0; i < DailyLogs.length; i++) {
if (DailyLogs[i].created_at >= this.state.startMonth && DailyLogs[i].created_at <= this.state.finishMonth && md.hasOwnProperty(DailyLogs[i].created_by_id)) {
md[DailyLogs[i].created_by_id]++;
}
}
You can also avoid the repeated DailyLogs[i]
by using a variable in the loop body:
var log = DailyLogs[i];
if (log.created_at >= ...)
In modern ES2015+ environments, you can combine for-of
with destructuring:
for (const {created_at, created_by_id} of DailyLogs) {
if (created_at >= this.state.startMonth && created_at <= this.state.finishMonth) {
switch (created_by_id) {
case "37aa0778-c148-4c04-b239-18885d46a8b0": md1++; break;
case "869a7967-ffb3-4a20-b402-ad6d514472de": md2++; break;
case "92c0f155-ce82-4b50-821f-439428c517a3": md3++; break;
case "aa9eb0f2-35af-469a-8893-fc777b444bed": md4++; break;
case "967d63ea-492c-4475-8b08-911be2d0bf22": md5++; break;
case "47ec8d60-1fa2-4bf5-abc8-34df6bd53079": md6++; break;
case "92c0f155-ce82-4b50-821f-439428c517a3": md7++; break;
}
}
}
Those options can be combined in various ways, for instance:
const md = {
"37aa0778-c148-4c04-b239-18885d46a8b0": 0,
"869a7967-ffb3-4a20-b402-ad6d514472de": 0,
"92c0f155-ce82-4b50-821f-439428c517a3": 0,
"aa9eb0f2-35af-469a-8893-fc777b444bed": 0,
"967d63ea-492c-4475-8b08-911be2d0bf22": 0,
"47ec8d60-1fa2-4bf5-abc8-34df6bd53079": 0,
"92c0f155-ce82-4b50-821f-439428c517a3": 0
};
for (const {created_at, created_by_id} of DailyLogs) {
if (created_at >= this.state.startMonth && created_at <= this.state.finishMonth && md.hasOwnProperty(created_by_id)) {
md[created_by_id]++;
}
}
Upvotes: 4
Reputation: 2075
Assuming you are merely counting, I would reccommend a map. This makes it easier to add more ids.
var counter = {
'37aa0778-c148-4c04-b239-18885d46a8b0': 0,
'869a7967-ffb3-4a20-b402-ad6d514472de': 0
}
function count(logs) {
logs.filter(function(entry) {
return entry.created_at >= this.state.startMonth &&
entry.created_at <= this.state.finishMonth &&
counter.hasOwnProperty(entry.created_by_id)
}).forEach(function(entry) {
counter[entry.created_by_id]++;
})
}
Upvotes: 2
Reputation: 386654
You could store the id to check against in an object and update the the count.
var ids = {
"37aa0778-c148-4c04-b239-18885d46a8b0": 0,
"869a7967-ffb3-4a20-b402-ad6d514472de": 0,
"92c0f155-ce82-4b50-821f-439428c517a3": 0,
"aa9eb0f2-35af-469a-8893-fc777b444bed": 0,
"967d63ea-492c-4475-8b08-911be2d0bf22": 0,
"47ec8d60-1fa2-4bf5-abc8-34df6bd53079": 0,
"92c0f155-ce82-4b50-821f-439428c517a3": 0
};
DailyLogs.forEach(({ created_at: at, created_by_id: id }) => {
if (at >= this.state.startMonth && at <= this.state.finishMonth && id in ids) {
ids[id]++;
}
});
Upvotes: 1
Reputation: 781210
Any time you find yourself creating variables in numeric sequence you should probably be using an array. Or in this case, you could use an object whose keys are the IDs you want to match.
var md = {
"37aa0778-c148-4c04-b239-18885d46a8b0": 0,
"869a7967-ffb3-4a20-b402-ad6d514472de": 0,
...
};
DailyLogs.forEach(l =>
l.created_at >= this.state.startMonth &&
l.created_at <= this.state.finishMonth && l.created_by_id in md &&
md[l.created_by_id]++
);
Upvotes: 2