仅当阵列不存在时才推送到阵列

时间:2013-12-09 19:45:25

标签: jquery arrays push

我有几个复选框可根据选中的复选框过滤产品。单击复选框时,过滤器将起作用,并且会将产品ID添加到阵列中。正如您所看到的,两个过滤器都具有一些相同的ID,因此如果它们单击多个输入框,我想确保仅将ID推入数组一次。例如。如果他们选择了input.white并选择了input.greymelange,那么他们点击了filter-btn我只想重复一次推送id。有没有办法可以做到这一点?

JQUERY

var productIds = [""];

$(document).on('click', 'a.filter-btn', function(e){

    $( ".listingTemplate" ).html("");
   if ($('input.white').is(':checked')) {
          productIds.push("4021401143741", "4021402266227");
    } 

   if ($('input.greymelange').is(':checked')) {
          productIds.push("4021401143741", "4021402266227","4021402266418", "4021401143796");
    } 
});

HTML

 <input type="checkbox" id="white" class="white" value="white" />                
 <input type="checkbox" id="greymelange" class="greymelange" value="greymelange" />
<a href="#" class="filter-btn">filter</a>

6 个答案:

答案 0 :(得分:4)

您可以使用$.inArray()$.each()

1)将所有新值保留在数组 deArray 中 2)使用$.each迭代此数组,然后查找它是否在 productIds 使用inArray()

if ($('input.greymelange').is(':checked')) {
        var deArray = ["4021401143741", "4021402266227", "4021402266418", "4021401143796"];
        $.each(deArray, function (i, j) {
            if ($.inArray(j, productIds) == -1) {
                productIds.push(j);
            }
        });
    }

建议:不要在数组中声明空字符串。

var productIds = [""];  //considered as an string. This will affect 
                        //when you check length, now it is 1
var productIds = []; //length is 0

最后,

var productIds = [];

$(document).on('click', 'a.filter-btn', function (e) {
    $(".listingTemplate").html("");
    if ($('input.white').is(':checked')) {
        var dArray = ["4021401143741", "4021402266227"];
        $.each(dArray, function (i, j) {
            if ($.inArray(j, productIds) == -1) {
                console.log(j)
                productIds.push(j);
            }
        })
    }

        if ($('input.greymelange').is(':checked')) {
            var deArray = ["4021401143741", "4021402266227", "4021402266418", "4021401143796"];
            $.each(deArray, function (i, j) {
                if ($.inArray(j, productIds) == -1) {
                    productIds.push(j);
                }
            })
        }
            console.log(productIds)
        });

<强> JSFiddle

答案 1 :(得分:2)

如果您只有一组固定的产品ID,为什么需要一个可变长度数组来存储哪些产品ID?

我建议建立一个包含你可以使用的逻辑的对象。

function productMapper() {
    var colorToIdMap = {
        'white' = [
            '4021401143741',
            '4021402266227'
        ],
        'greymelange' = [
            '4021401143741',
            '4021402266227',
            '4021402266418',
            '4021401143796'
        ]
    };
    var selectedIds = [];
    function selectIds(color) {
        this.selectedIds = [];
        var colorIds = this.colorToIdMap[color];
        for(i = 0; i < colorIds.length; i++) {
           var currentId = colorIds[i];
           if(this.selectedIds.indexOf(currentId) === -1) {
               this.selectedIds.push(currentId);
           }
        }
    }
    function getSelectedIds() {
        return this.selectedIds;
    }
}

用法可能是:

var selectedProductMap = new productMapper();

$(document).on('click', 'a.filter-btn', function(e){

    $( ".listingTemplate" ).html("");
    if ($('input.white').is(':checked')) {
          selectedProductMap.selectIds('white');
    } 

    if ($('input.greymelange').is(':checked')) {
          selectedProductMap.selectIds('greymelange');
    } 
});

这样做的好处是,当您添加新颜色和产品ID时,很容易将它们添加到此类中(或者从数据库中动态构建该类部分。

我还建议考虑重构HTML,这样就不需要为每个颜色选项添加if条件。也许给所有复选框输入一个公共类,并从input属性派生颜色值。这样的事情可能会出现在你的onclick函数中:

$('input.filterCheckbox').each(function(index.value)) {
    var $currentCheckbox = $(this);
    if($currentCheckbox.is(':checked')) {
        selectedProductMap.selectIds($currentCheckbox.val());
    }
}

var currentlySelectedIds = selectedProductMap.getSelectedIds();

答案 2 :(得分:0)

在添加到列表之前,您需要检查项目是否包含在内。不幸的是,这并不像应该的那样容易,但下面的堆栈解释了:How do I check if an array includes an object in JavaScript?

由于您将此标记为jQuery,因此以下(示例)代码可能适合您:

if ($.inArray("4021401143741", productIds) === -1)
   productIds.push("4021401143741");

有关此致电see here的更多信息。祝你好运!

答案 3 :(得分:0)

要检查数组中是否已存在某个项目,您可以使用Array.indexOf。请注意,在IE中本地不存在&lt; 9,但我已经发布了一个剪下来的代码,如果它不可用,它将把它添加到Array原型中。

var products = [];
function addProducts() {
    for(var i = 0, l = arguments.length; i < l; i++) {
        if(products.indexOf(arguments[i]) === -1) {
            products.push(arguments[i]);
        }
    }
}
//Add indexOf if it doesn't exist natively
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(elt) {
        var len = this.length >>> 0;
        var from = Number(arguments[1]) || 0;
        from = (from < 0)
             ? Math.ceil(from)
             : Math.floor(from);
        if (from < 0)
          from += len;

        for(; from < len; from++) {
          if(from in this && this[from] === elt)
            return from;
        }
        return -1;
    };
}

然后,要使用这些新功能,您可以将代码修改为:

$(document).on('click', 'a.filter-btn', function(e) {
    if($('input.white').is(':checked')) {
        addProducts("4021401143741", "4021402266227");
    }
    if($('input.greymelange').is(':checked')) {
        addProducts("4021401143741", "4021402266227","4021402266418", "4021401143796");
    }
});

正如旁注。如果可以避免,则不应将事件绑定到文档。如果您使用大量事件,则将事件绑定到文档可能会导致性能问题。每次触发click事件时,此函数将运行以检查目标是否与指定的目标匹配。要限制此性能命中,您应该将它们绑定到最接近的非更改元素。在表单内部输入的示例中,您可以将其添加到表单中。

答案 4 :(得分:0)

将以下代码添加到缺血条件中。 // Continue execution推送价值观。

isSet = false;
currentVal = '999999999999';
$.each(productIds, function( index, value ) {
  if(value == currentVal){
     isSet = true;
  }
});

if(isSet){
// Continue execution
} else {
// failure
}

答案 5 :(得分:0)

它需要是一个数组吗?听起来你最好不要使用普通物体:

productIds[ 420… ] = true;

这取决于你的其余代码,但听起来你想要实现一个哈希/查找表/字典而不是一个数组 - 以这种方式检查存在也会更直接。