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

时间:2018-08-31 09:27:06

标签: javascript arrays for-loop if-statement

我当前正在使用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++; }
  }
}

除了拥有多个if语句,或者以某种方式缩短它之外,还有更好的方法吗?

4 个答案:

答案 0 :(得分:4)

通过使用DECLARE @Test AS table ( customerid int, Number int, DateFrom int, DateTo int ); INSERT INTO @Test VALUES (1, 240, 201710, 201712), (1, 240, 201712, 201801), (1, 240, 201801, 201803), (1, 300, 201803, 201805), (1, 240, 201805, 999999); SELECT t.customerid, t.Number, t.DateFrom, t.DateTo FROM @Test t; SELECT customerid, STUFF( (SELECT DISTINCT ', ' + CONVERT(varchar(100), (t2.DateFrom)) + ' - ' + CONVERT(varchar(100), (t2.DateTo)) + ' : ' + CONVERT(varchar(100), (t2.Number)) FROM @Test t2 FOR XML PATH('')), 1, 2, '') AS Text FROM @Test t WHERE t.customerid = t2.customerid GROUP BY t.customerid; 可以使其效率(略)更高,因为如果更早的else if的条件成立,那么根据定义就不可能。

JavaScript中的if较长序列可以改为写成else if

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; } } } else if很大程度上取决于样式。

另一种选择是将计数器保留在由switch键控的对象中:

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

DailyLogs[i]

在现代ES2015 +环境中,您可以将var log = DailyLogs[i]; if (log.created_at >= ...) 与解构结合:

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

答案 1 :(得分:2)

假设您只是在数数,我推荐一张地图。这样可以更轻松地添加更多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]++;
  })
}

答案 2 :(得分:2)

每当您发现自己以数字顺序创建变量时,您可能应该使用数组。或者在这种情况下,您可以使用一个对象,其键是要匹配的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]++
);

答案 3 :(得分:1)

您可以将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]++;
    }
});