首页 > 解决方案 > 有效地检查对象数组循环中的许多条件

问题描述

我有一个对象数组,一个属性是它们的状态,我需要计算以下状态:如果所有状态都失败返回“失败”,如果全部取消返回“取消”,依此类推,但如果数组有一个失败,或者一个取消返回“部分完成”,我做到了,但我循环了很多,我觉得存在一种更好、更有效的方法来做同样的事情,这是我的代码:

function getComputedStatus(list) {

      if (list.every(status => status.statusName == 'Failed'))
          return 'Failed';

      if (list.every(status => status.statusName == 'Canceled'))
          return 'Canceled';

      if (list.every(status => status.statusName == 'DidNotRun'))
          return 'DidNotRun';

      if (list.some(status => status.statusName == 'InProgress' ||
          status.statusName == 'Pending'))
          return 'InProgress';

      if (list.some(status => status.statusName === 'Failed'   ||
                              status.statusName === 'Canceled' ||
                              status.statusName === 'DidNotRun'))
         return 'PartiallyCompleted';

      return 'Completed';
}

标签: javascriptecmascript-6

解决方案


所以,看来你的逻辑实际上是这样的:

  1. 您有一组状态对象。
  2. 如果任何状态为“InProgress”或“Pending”,则返回“InProgress”
  3. 如果所有状态都相同并且是“失败”、“取消”或“DidNotRun”,则返回该值。
  4. 如果任何状态为 'Failed'、'Canceled' 或 'DidNotRun',则返回 'PartiallyCompleted'
  5. 否则,返回“完成”

因此,如果您能够弄清楚如何通过一次遍历数组而不是 5 次部分遍历数组来完成所有这些检查,那么执行效率将会大大提高。

这是一种方法:

const doneStatuses = new Set(["Failed", "Canceled", "DidNotRun", "Completed", "InProgress"]);

function getComputedStatus(list) {
    const allStatuses = new Set();

    // collect all status values in a Set object
    for (let status of list) {
        allStatuses.add(status.statusName);
    }

    // if all the statusName values were the same and they were  
    // "Failed", "Canceled", "DidNotRun", "InProgess" or "Completed"
    // then return that specific status
    if (allStatuses.size === 1) {
        let theStatus = Array.from(allStatuses)[0];
        if (doneStatuses.has(theStatus)) {
            return theStatus;
        }
    }
    // if any status was "InProgress" or "Pending", return "InProgress"
    if (allStatuses.has("InProgress") || allStatuses.has("Pending")) {
        return "InProgress";
    }

    // If any status was "Failed", "Canceled" or "DidNotRun" (but not all)
    // then return "PartiallyCompleted"
    if (allStatuses.has("Failed") || allStatuses.has("Canceled") || allStatuses.has("DidNotRun")) {
        return "PartiallyCompleted";
    }

    // otherwise, return "Completed"
    return "Completed";
}

推荐阅读