使用此特定代码从另一个数组中删除一个数组[重复]
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 && 0 != 193)
,即(true && false)
,即false
,这意味着[317, 0]
将被错误地删除。该函数必须为[317, 193]
返回false
only。这就是为什么你想要||
而不是&&
。【参考方案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 );
//
【讨论】:
以上是关于使用此特定代码从另一个数组中删除一个数组[重复]的主要内容,如果未能解决你的问题,请参考以下文章
使用 findIndex() 从数组中删除特定元素 - React [重复]