一个简单的检查,如果选择,如果没有添加到Javascript数组



该函数应该获取所选行的id并检查它是否在数组中,如果不在数组中,则将其添加到数组中,否则将其从数组中删除。问题是我似乎搞不清事情的顺序。循环不会一直运行(因为break),但是如果我删除break,而图像更改(复选框)工作,数组仍然是错误的。

我也不明白为什么尽管在这个函数外面声明了deleteString = [];,没有把它放在函数里面,deleteString.push(orderId);的调用失败了

这个问题似乎很明显,在第一次运行时,无论数组有多大,无论检查是否匹配,循环的其余部分都不会运行。因此,也许我应该做一个检查,等待循环完成,然后再使用found/not-found的结果。

function passSelection(orderId) {
  // check if empty
  if (deleteString.length == 0) {
    // turn into array
    deleteString = [];
    // first entry
    deleteString.push(orderId);
    // mark this row as checked
    $("#"+"select-box-"+orderId).attr('src', 'images/red-checked.png');
  }
  else {
    // not the first order
    // check if already in array
    // get length of array
    var delStrLen = deleteString.length;
    // loop through array
    for (var i = 0; i < delStrLen; i++) {
      if (deleteString[i] == orderId) {
        // match found, remove from deleteString array
        deleteString.splice(i, 1);
        // update the row
        $("#"+"select-box-"+orderId).attr('src', 'images/unchecked.png');
        break;
      }
      else {
        // not in the array
        // add to array
        deleteString.push(orderId);
        // update row
        $("#"+"select-box-"+orderId).attr('src', 'images/red-checked.png');
        break;
      }
    }
  }
}

应该使用indexOf来测试数组中元素是否存在。indexOf返回搜索项的位置,如果找不到元素则返回-1所以,这是我重构和测试过的代码

var deleteString = [];
function passSelection(orderId) {
  // check if empty
  let orderPos = deleteString.indexOf(orderId);
  if (orderPos == -1) {
    // first entry
    deleteString.push(orderId);
    // mark this row as checked
    $("#"+"select-box-"+orderId).attr('src', 'images/red-checked.png');
  }
  else {
    // match found, remove from deleteString array
    deleteString.splice(orderPos, 1);
    // update the row
    $("#"+"select-box-"+orderId).attr('src', 'images/unchecked.png');
  }
}

首先删除for循环中的元素不是一个好主意,因为你正在操作你正在遍历的数组。要查找数组中的项,应该使用indexOf方法。

function passSelection(orderId) {
  // check if empty
  if (deleteString.length == 0) {
    // turn into array
    deleteString = [];
    // first entry
    deleteString.push(orderId);
    // mark this row as checked
    $("#"+"select-box-"+orderId).attr('src', 'images/red-checked.png');
  }
  else {
    // not the first order
    // check if already in array
    // get length of array
    var delStrLen = deleteString.length;
    // loop through array
    var index = deleteString.indexOf(orderId);
      if (index > -1) {
        // match found, remove from deleteString array
        deleteString.splice(index, 1);
        // update the row
        $("#"+"select-box-"+orderId).attr('src', 'images/unchecked.png');
        break;
      }
      else {
        // not in the array
        // add to array
        deleteString.push(orderId);
        // update row
        $("#"+"select-box-"+orderId).attr('src', 'images/red-checked.png');
        break;
      }
  }
}

实际上您不需要第一个条件来检查数组长度是否为零。并从else条件中移除break。正如dasoro建议的那样,使用indexOf方法。而不是循环。也请尝试张贴一个完整的jsfiddle的例子,以便每个人都能很容易地理解你的逻辑。请看修改后的代码

function passSelection(orderId) {
  if (!deleteString) deleteString = [];
  var index = deleteString.indexOf(orderId);
  if (index !== -1) {
    deleteString.splice(index, 1);
    $("#"+"select-box-"+orderId).attr('src', 'images/unchecked.png');
  } else {
    deleteString.push(orderId);
    $("#"+"select-box-"+orderId).attr('src', 'images/red-checked.png');
}

您的问题是您在循环中添加了元素。你应该在循环中检查是否存在,然后添加/删除你的项目一次。您也不需要对空数组进行特殊检查,您的循环不会触发,它将按预期工作:

function passSelection(orderId) {
    var isFound = false;
    for (var i = 0; i < deleteString.length; i++) {
        if (deleteString[i] == orderId) {
            isFound = true;
        }
    }
    if (isFound) {
        deleteString.splice(i, 1);
        $("#" + "select-box-" + orderId).attr('src', 'images/unchecked.png');
    } else {
        deleteString.push(orderId);
        $("#" + "select-box-" + orderId).attr('src', 'images/red-checked.png');
    }
}
总的来说,你的方法太难了。您可以简单地使用Set对象并以更好,更方便和性能的方式实现此结果。
Set方法是O(1)算法,而遍历你的数组是O(N)算法,这意味着它可以慢几千倍。
var set = new Set();
function passSelection(orderId) {
    if (set.has(orderId)) {
        $("#"+"select-box-"+orderId).attr('src', 'images/unchecked.png');
        set.delete(orderId);
    } else { 
        $("#"+"select-box-"+orderId).attr('src', 'images/checked.png');
        set.add(orderId);
    }
}

如果你需要ecmascript 6之前的浏览器支持,那么你可以用同样的方式利用对象属性:

var set = {};
function passSelection(orderId) {
    if (set[orderId]) {
        $("#"+"select-box-"+orderId).attr('src', 'images/unchecked.png');
        delete set[orderId];
    } else { 
        $("#"+"select-box-"+orderId).attr('src', 'images/checked.png');
        set[orderId] = true;
    }
}

初始化数组以避免检查是否存在

var arr = [ 4,5,6,1,23 ];
function remove(orderId) {
        var src;
        var index;
        index = arr.indexOf(orderId);
        if (index === -1) {
                arr.push(orderId);
                src = 'images/unchecked.png';
        } else {
                arr.splice(1,index);
                src = 'images/red-checked.png';
        }
        $("#"+"select-box-"+orderId).attr("src",src);
}
// Test item which is in the array (it should be removed)
remove(5);
console.log(arr);
// Test item which is not in the array (it should be added)
remove(24);
console.log(arr);

最新更新