【问题标题】: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?
        }
    });
}

泰!

【问题讨论】:

    标签: javascript jquery


    【解决方案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.orghttp://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 );
        
        //
        

        【讨论】:

          猜你喜欢
          • 2018-12-14
          • 1970-01-01
          • 2021-07-27
          • 1970-01-01
          • 2013-02-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多