使用此特定代码从另一个数组中删除一个数组[重复]

Posted

技术标签:

【中文标题】使用此特定代码从另一个数组中删除一个数组[重复]【英文标题】:Removing one array from another array, using this particular code [duplicate] 【发布时间】:2013-08-15 05:21:13 【问题描述】:

我有以下数组,其中包含其他数组(它们实际上是 html5 画布的坐标)。

var crossesPos = [[317, 193], [110, 334], [390, 347], [281, 222], [307, 384], [329, 366], [230, 104], [276, 156], [173, 330], [227, 100], [397, 261], [341, 389], [233, 223], [261, 350], [267, 286]]

别说:

x = 317;
y = 193;

在以下函数中,如何从 crossesPos 中删除数组 [317,193]?

function checkForCrosses(x,y)
    var position;
    jQuery.each(crossesPos, function()
        position = this;
        if(x == position[0] && y == position[1])
            // how do I remove the array [317,193] from crossesPos?
        
    );

泰!

【问题讨论】:

【参考方案1】:

使用以下代码拼接数组中的精确坐标。将此代码放入您的函数中。这比 JQuery 代码效率更高。

javascript

for(var i=0; i<crossesPos.length; i++)

    if(crossesPos[i][0] === x)
        if(crossesPos[i][1] === y)
        
            crossesPos.splice(i,1);
            break;
        


重要提示:如果要删除数组中的所有匹配元素(而不仅仅是一个),则必须编辑代码,删除break; 条件并反转循环

for(var i=crossesPos.length-1; i>=0; i--)

     if(crossesPos[i][0] === x)
        if(crossesPos[i][1] === y) crossesPos.splice(i,1);          


Working demo (with sexy output)


Performance comparison (test it yourself!)

这是(在本文发布时)满足您需求的最有效和最高效的方式,因为最接近的结果仍然比我的答案慢 90%

【讨论】:

我的回答有什么问题? 我不是反对者,但我怀疑这与for .. in有关(至少根据我的经验)是不鼓励的。 @cdhowie 你是对的。我刚刚意识到for ... in 会对性能产生巨大影响! @cdhowie 我还包括了性能比较。这实际上使脚本的性能比我的旧 for ... in 慢了 98% 是的,grep 并不快。我选择它的唯一原因是因为它是 jQuery 中的一个解决方案并且易于理解。但就性能而言,你无法击败array.splice()【参考方案2】:

执行此操作的“jQuery 方式”是使用jQuery.grep():

var crossesPos = [[317, 193], [110, 334], [390, 347], [281, 222], [307, 384],
                  [329, 366], [230, 104], [276, 156], [173, 330], [227, 100],
                  [397, 261], [341, 389], [233, 223], [261, 350], [267, 286]];

crossesPos = jQuery.grep(crossesPos,
                         function(e)  return e[0] === 317 && e[1] === 193; ,
                         true);

(See it run)

【讨论】:

投反对票的人愿意解释他们的投票吗?此代码已经过测试并且可以正常工作。 似乎有人无缘无故地投反对票。我其实不知道$.grep(),所以谢谢你的回答!【参考方案3】:

使用 jQuery 的 grep 实用函数:

var x = 317,
    y = 193,
    newPos = $.grep(crossesPos, function(n, i)
          return (n[0] != x || n[1] != y);
    );

【讨论】:

测试应该是(n[0] != x || n[1] != y) 再读一遍 - 要求删除数组[317, 193] 是的,此代码还将删除 [317, 0][0, 193] 呃,我想你很困惑。如果 x 为 317 且 y 为 193 在同一个数组(即 [317, 193] )中,则不会返回。它将返回所有其他内容,这是必需的。 对于[317, 0],条件为(317 != 317 &amp;&amp; 0 != 193),即(true &amp;&amp; false),即false,这意味着[317, 0]将被错误地删除。该函数必须为[317, 193] 返回false only。这就是为什么你想要|| 而不是&amp;&amp;【参考方案4】:

你应该使用 .splice() 函数。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

crossesPos.splice(index,1);

【讨论】:

【参考方案5】:

我认为您需要使用 splice() 删除找到的项目。 This 是个工作狂。打开控制台查看修改后的数组。

要添加到您的函数的代码:

function checkForCrosses(x, y)
    var position,
        length = crossesPos.length;

    for (var i = length; i > 0; i--) 
      position = crossesPos[i - 1];

      if (x == position[0] && y == position[1])
        crossesPos.splice(i - 1, 1);
    

【讨论】:

虽然这可行,但它并没有达到您的预期。 .each() 循环遍历原始数组的长度。在迭代时对其进行修改不会改变这一点,因此循环会迭代不再存在的索引。而且由于您鼓励使用 this 而不是回调的第二个参数,因此您正在检查窗口的属性。如果要删除元素(而不是返回已接受元素的新数组),则应使用普通的 for/while 循环并向后迭代 啊,哎呀,你是对的,反向的 for/while 循环可以解决问题。 Plunk 更新为反向使用 for 循环。【参考方案6】:

http://underscorejs.org 或 http://lodash.com 可以使这变得非常容易,但如果你坚持直接做:

var pos = -1;
jQuery.each(crossesPos,function(idx,item) 
  if (x===item[0] && y===item[1]) 
    pos = idx;
  
);
crossesPos.splice(idx,1);

或者更简单

var ary = [];
jQuery.each(crossesPos,function(idx,item) 
  if (x!==item[0] || y!==item[1]) 
    ary.push(item);
  
);
crossesPos = ary;

【讨论】:

【参考方案7】:

使用filter

function checkForCrosses(x,y)
    function myFilter(element, index, array) 
        return (element[0] != x || element[1] != y);
    
    crossesPos = crossesPos.filter(myFilter);

然后crossesPos 持有没有[317, 193] 的数组

【讨论】:

你的条件不对,已经有人指出如果你要使用“不等于”的方法应该是element[0] != x || element[1] != y 如果[317, 0][0, 193]crossesPos 中,此代码还将删除它们。 哦,没错,我需要复习我的布尔代数 :)【参考方案8】:
//
//
//  here's some common Array operations you might find usefull and familiar: 
//   
// .each( callback, boolFlgFromLast )
//   # iterate an array runing given callback-fn for every array item, 
//   # pass it curent array key and value, respectively, 
//   # set context of the callback to host array, 
//   # if boolFlgFromLast argument is ( === )true, iterate from last element, 
//   # break iteration if callback returns ( === )false, 
//   # return iterated array
//
// .not( callback ) 
//   # remove items for which callback returns ( === )true
//   # keep others
//   # return host array
//  
// .keep( callback )
//   # keep items for which callback returns ( === )true
//   # remove others
//   # return host array
//
// .desparse()
//   # 'desparse' host array in place
//   # return host array
// 
//
//    var
//       a = [ 
//               [317, 193], 
//               [110, 334], 
//               [390, 347], 
//            ];
//    
//  
//    a
//     .each( function ( k, v )  console.log('['+ k +'] -> '+ v );  )
//     .not(  function ( k, v )  console.log(' * '); return ( v[0] == 317 ) && ( v[1] == 193 );  )
//     .each( function ( k, v )  console.log('['+ k +'] -> '+ v );  )
//     .keep( function ( k, v )  console.log(' * '); return Math.random() > .1;  )
//     .each( function ( k, v )  console.log('['+ k +'] -> '+ v + ', [ this === a ] -> '+ ( this === a )  );  );
//       
//     // make sparse array
//     a[5] = [0,0];
//     console.log('sparse array: ', a);
//     
//     a
//     .desparse()
//     .each( function ( k, v )  console.log('['+ k +'] -> '+ v );  )
//       
//
//
;( function( _a )  

    var
        t  = !0, 
        f  = !t;

    _a.each = function ( fn )  

                    var
                       len = this.length, 
                       i   = 0;

                    for( ; i < len ; i++ )  
                       if ( fn.call( this, i, this[i] ) === f ) break;
                    

                    return this;

    ;

    overload( 'each', _a, function ( fn, flgIterateBackwards ) 

                              if ( flgIterateBackwards === t ) 

                                  var
                                     i = this.length - 1;

                                   for ( ; i >= 0 ; i-- )  
                                       if ( fn.call( this, i, this[i] ) === f ) break;
                                   

                                   return this;

                               else 

                                  return this.each( fn );

                              
                           
            );

    _a.not = function ( callback )  
                  return this.each( function ( k, v )  
                                      ( callback.call( this, k, v ) === t ) && this.splice( k, 1 );
                                    , t );
             ;

    _a.keep = function ( callback )  
                  return this.each( function ( k, v )  
                                       ( callback.call( this, k, v ) === t ) || this.splice( k, 1 );
                                    , t );
              ;


    _a.desparse = function ()  
        return this.not( function ( k, v )  return k in this === f;  );
    ;


    // helper fn-s

    function overload ( fn, obj,  newfn )  

       return ( function ( origfn )  

            obj[fn] = function () 

                        var
                            args = _a.slice.call( arguments );

                        if ( newfn.length == arguments.length ) 

                            return newfn.apply( this, args )

                         else if ( isfn ( origfn ) ) 

                            return origfn.apply( this, args )

                         else 
                            // ignore non method props
                        

                      ;

         )( obj[fn] );
       

    function isfn ( o )  
       return ( typeof o === 'function' ) && 
              ( Object.prototype.toString.call( o ) === '[object Function]' );
    


 )( Array.prototype );

//

【讨论】:

以上是关于使用此特定代码从另一个数组中删除一个数组[重复]的主要内容,如果未能解决你的问题,请参考以下文章

怎么用JS把特定字符串重复的字符删除留下一个

使用 findIndex() 从数组中删除特定元素 - React [重复]

空手道 DSL - 使用重试直到检查数组,直到所有项目中都存在特定的键值对[重复]

从另一个数组列表中删除一个数组列表元素的最佳方法

如何去掉一个数组的重复元素:数组去重

swift 3 - 从另一个数组中存在的数组中删除对象