【问题标题】:jquery exclude array elementsjquery排除数组元素
【发布时间】:2016-01-12 03:49:26
【问题描述】:

我有一个想要有效维护的元素数组,随着时间的推移添加和删除元素数组。

var myElements = $('.initial');

jquery 的merge() 似乎非常适合添加项目,因为它不会创建新数组而只是添加到现有数组:

$.merge(myElements, $('.to-add'));

是否有等效的删除方法,也可以就地修改数组?比如:

$.exclude(myElements, $('.to-remove'));

我确实有 DOM 元素的数组,选择器只是用作示例。

【问题讨论】:

  • @adamj 看起来 splice 只能删除由索引和长度给出的一系列元素,而我想从另一个数组中删除元素,该数组可以以任何顺序存在于任何位置。
  • @jozxyqk 注意,将jQuery() 作为参数传递给$.exclude() 将创建一个新对象

标签: javascript jquery arrays set set-operations


【解决方案1】:

假设你在 a 中寻找 b 的相对补码。 而且您不想在处理时创建其他对象。 该函数适用于普通数组和 jQuery 集。 (因此使用 $.each、$.inArray 而不是 Array.prototype.forEach Array.prototype.indexOf)

我写了一个符合你要求的函数。

$.exclude = function(a,b) {
    var idx;
    $.each(b, function(i, val) {
      while((idx = $.inArray(val, a)) !== -1) {
         a.splice(idx, 1);         
      }
    })
    return a;
}

在这里测试这段代码 https://jsfiddle.net/happyhj/uwd4L1dm/8/

你可以这样使用。

$.exclude(myElements, $('.to-remove'));

【讨论】:

  • 在我看来更像 O(n * m)。您可以用indexOf 替换其中一个循环,但使用splice 就地删除元素的要点似乎是要走的路。
  • @jozxyqk jQuery 设置没有 indexOf 功能。但这是个好建议。我将使用 $.inArray()。
【解决方案2】:

使用jquerynot方法,

var filtered = $(myElements).not($('.to-remove'));

【讨论】:

  • 虽然不是就地的,但这与我所追求的非常接近。没有意识到 not() 可以使用数组,而不是选择器或元素。
  • 你可以使用not()创建自己的排除函数。
  • 我的就地问题是为了提高效率。每次删除都会留下一个未使用的数组供垃圾收集器处理。随着数组大小的增加,这将开始减慢速度。
  • @charlietfl 在我的情况下,我有一个数组,而不是一个选择器(仅用作示例)。 azzi 将其包含在此答案中是正确的。
【解决方案3】:

您可以使用delete 从数组中删除一个元素,然后使用$.grep 删除空白空间。

//[0] since $("#id") will be a jquery Object
//[0] will return the particular DOM element

var orgArray = [$("#merge1")[0],$("#merge2")[0],$("#merge3")[0]];
var secArray = [$("#merge4")[0],$("#merge5")[0]]

// Will merge other two values; 
// jQuery merge will merge contents of 
//two array into first array

var merArray = $.merge(secArray, orgArray);

// Want to remove $("#merge2");

var getIndex = merArray.indexOf($("#merge2")[0]);
    if(getIndex >-1){
     delete merArray[getIndex] 
    }

// length before filtering
$("#l1").text(merArray.length);

//Now will remove Empty Space

merArray = $.grep(merArray,function(n){
 return n==0 || n
});
$("#l2").text(merArray.length);

JSFIDDLE

【讨论】:

    【解决方案4】:

    您正在使用用于数组字面量的方法。 jQuery 已经有了 add() 方法,它将返回一个修改后的 jQuery 对象,其中包含与选择器匹配的元素

    var myElements = $('.initial');
    var newCollection = myElements.add('.to-add');    
    newCollection.not('.to-remove').doSomething();
    

    不要将 jQuery 对象视为数组,尽管它们是 类似数组的

    参考add()

    目前尚不清楚您的总体目标到底是什么,但很可能您可以使用 api 中已经存在的任意数量的过滤方法来管理它

    【讨论】:

    • .not() 创建一个新的 jQuery 对象
    • @guest271314 不确定相关性是什么。它不会改变newCollection,只需将该新对象传递给链中的下一个方法
    • “.not() 方法从匹配元素的子集构造一个新的 jQuery 对象。” api.jquery.com/not 。要求似乎不是创建新的 jQuery 集合或数组?只推送到newCollection 或从中删除?虽然在 OP,不确定为什么,一个新的 jQuery 对象作为参数传递给 $.exclude() ?并且 OP 没有直接在 Question 中解决 js 的这一部分;在这里,关于需求的解释可能是不正确的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多