简体   繁体   English

更有效的方式搜索数组中的多个对象

[英]More efficient way search for multiple objects in array

I am currently using a for loop and multiple if statements to count the number of records that match a string. 我目前正在使用for循环和多个if语句来计算与字符串匹配的记录数。

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. 除了拥有多个if语句,或者以某种方式缩短它之外,是否有更好的方法来做到这一点。

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. 通过使用else if ,可以(略)提高效率,因为如果if的条件较早, if条件成立,根据定义,以后的条件就不可能。

Long series of else if in JavaScript can be written as switch instead. 较长的else if序列( else if在JavaScript中)可以写成switch

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. 在这种情况下,使用else if vs. switch主要取决于样式。

Another option is to maintain your counters in an object keyed by the created_by_id : 另一个选择是将计数器保留在由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: 您还可以通过在循环体内使用变量来避免重复的DailyLogs[i]

var log = DailyLogs[i];
if (log.created_at >= ...)

In modern ES2015+ environments, you can combine for-of with destructuring: 在现代ES2015 +环境中,您可以将for-of与销毁相结合:

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

Assuming you are merely counting, I would reccommend a map. 假设您只是在数数,我推荐一张地图。 This makes it easier to add more ids. 这样可以更轻松地添加更多ID。

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

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. 或者在这种情况下,您可以使用一个对象,其键是要匹配的ID。

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

You could store the id to check against in an object and update the the count. 您可以将ID存储起来以检查一个对象并更新计数。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM