1

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.

4
  • 1
    What are the mds? Commented Aug 31, 2018 at 9:27
  • do you have more than the given created_by_id values? Commented Aug 31, 2018 at 9:28
  • just a global variable that holds the value. @NinaScholz Commented Aug 31, 2018 at 9:30
  • Judging from the hardcoded md* values it looks like you are counting the number of daily logs each user has submitted. May I suggest you to use some sort of "group by" operation in the database you are using? Most SQL engines come with such a feature, and it is better to do so in SQL. Particularly because the number of md* (users) may increase in future, which would require further code changes (in Javascript). Commented Aug 31, 2018 at 9:31

4 Answers 4

4

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]++;
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Wow lots of options and ideas, thank you for the depth of your response!
2

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]++
);

Comments

2

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]++;
  })
}

Comments

1

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]++;
    }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.