该函数应该获取所选行的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);