如何在没有for循环的情况下引用数组的多个索引值?
Posted
技术标签:
【中文标题】如何在没有for循环的情况下引用数组的多个索引值?【英文标题】:How to reference multiple index values of an array without a for-loop? 【发布时间】:2017-07-18 03:37:42 【问题描述】:如何在不遍历所有索引值的情况下指定数组的多个索引值?
我有一个数组:var boxArray = $(’.box’).toArray();
。我有 9 个元素的类 box
,所以这个数组由索引值 [0, 1, 2, 3, 4, 5, 6, 7, 8]
组成。
如果[0]
、[4]
和[8]
的boxArray
索引值都被赋予clicked
类,我希望发生一些事情。我知道我可以使用 for
循环遍历整个数组,并且我知道我只能引用一个索引值 (boxArray[0]
),但是我如何一次表示多个无序索引值?
$(boxArray[0, 4, 8])
不起作用 - 仅识别最后一个索引值。 $(boxArray[0][4][8])
不起作用
在 javascript 和 jQuery 中执行此操作的唯一方法是一次引用它们吗?理想情况下,我希望能够做这样的事情:
if ($(boxArray[0, 4, 8]).hasClass(‘clicked’))
// do something;
而不是
if ($(boxArray[0]).hasClass('clicked') &&
$(boxArray[4]).hasClass('clicked') &&
$(boxArray[8]).hasClass('clicked')
)
// do something
【问题讨论】:
是否可以为此提供小提琴? 迭代它们有什么问题? 我在那里添加了更多代码而不是 jsfiddle。我对 for 循环的问题是我需要参考的三个索引值的总共八个组合,其中几个是乱序的。我只是希望有一种神奇的非 for 循环方式来访问多个无序索引值。 为什么是0
、4
和 8
?他们有什么共同点?他们能被什么东西选中吗?
这是关于井字游戏的吗?因为有更简单的方法可以连续检查三个。
【参考方案1】:
你可以使用Array.prototype.every():
every() 方法测试数组中的所有元素是否通过提供的函数实现的测试。
sn-p:
var boxArray = $('.box').toArray();
var result = [1, 2, 4].every(function(element, index, array)
return boxArray[element].classList.contains('clicked');
);
console.log(result);
result = [0, 2, 4].every(function(element, index, array)
return boxArray[element].classList.contains('clicked');
);
console.log(result);
//
if ([0, 2, 4].every( (ele) => return $(ele).has('.clicked');))
console.log('test passed');
else
console.log('test not passed');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="box clicked">box</button>
<button class="box">box</button>
<button class="box clicked">box</button>
<button class="box">box</button>
<button class="box clicked">box</button>
<button class="box">box</button>
<button class="box">box</button>
<button class="box">box</button>
【讨论】:
【参考方案2】:您可以创建一个为您进行检查的函数(使用arguments
对象)。像这样:
function check(arr)
for(var i = 1; i < arguments.length; i++) // for each index (arguments after the first which is the array)
if( ! $(arr[arguments[i]]).hasClass('clicked') ) // if one of them doesn't have the class 'clicked' then return false
return false;
return true; // if all have the class clicked then return true
然后你可以这样称呼它:
if(check(boxArray, 0, 4, 8))
// boxArray[0], boxArray[4] and boxArray[8] have the class clicked
// or
if(check(boxArray, 0, 4, 8, 3, 1, 7, 11))
// all the .box elements at indexes 0, 4, 8, 3, 1, 7 and 11 have the class 'clicked'
// ...
注意:如果只传递数组作为参数 (check(boxArray)
),则返回值将是 true
。如果你想在这种情况下返回false
,那么只需将此行作为函数check
的第一行:
if(arguments.length <= 1) return false;
【讨论】:
【参考方案3】:您可以使用map() 方法或filter() 方法或every
方法(如@gaetanoM 的答案):
对于使用map
:
var boxArray = [];
$('.box').toArray().map((x, y, z) =>
if (y === 0 || y === 4 || y === 8) boxArray.push($(x));
);
boxArray.forEach(box =>
if (box.hasClass('clicked'))
// do something...
);
对于使用filter
:
var boxArray = $('.box').toArray().filter((x, y, z) =>
if (y === 0 || y === 4 || y === 8) return $(x);
);
boxArray.forEach(box =>
if (box.hasClass('clicked'))
// do something...
);
【讨论】:
这不是map
的用例。更多的是forEach
或filter
!
@ibrahimmahrir 我在答案中引用了文档。
map
用于从输入数组中返回一个数组 => 所以它只是浪费资源,不应该仅仅用于循环数组,这就是forEach
的用例。
filter
这样写代码会更清晰:var boxArray = $('.box').toArray().filter((x, y) => y === 0 || y === 4 || y === 8);
so it's just a waste of ressources and should not be used just to loop an array
。能不能给个文件说一下? MDN 文档没有提到这一点。【参考方案4】:
你可以使用jquery.fn.filter(function) please.then 你可以检查 filter(..).length==[2,8].length
$('button').click(function()
var selectors=[2,8];
$('.box').filter(function(index,element)
return selectors.indexOf(index)!=-1&&$(element).has('.checked');
).addClass('active');
);
.box
float:left;
border:1px solid #000;
width:80px;
height:50px;
margin:5px;
.active
color:red;
button
clear:both;
display:block;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>filter [2,8] without 4</button>
<div class='box'>.box</div>
<div class='box'>.box</div>
<div class='box checked'>.box .checked</div>
<div class='box'>.box</div>
<div class='box checked'>.box .checked</div>
<div class='box'>.box</div>
<div class='box'>.box</div>
<div class='box'>.box</div>
<div class='box checked'>.box .checked</div>
<div class='box'>.box</div>
【讨论】:
【参考方案5】:做到这一点的最短方法是
if ($(boxArray[0], boxArray[4], boxArray[8]).hasClass("clicked"))
// do something;
【讨论】:
在我的程序中,您的解决方案似乎只适用于第一个索引值 (boxArray[0]),对接下来的两个没有影响。也许这是我的特定代码,但是您确定与 jQuery 的逗号分隔吗?我希望它确保所有这三个索引值都具有“点击”类。道歉 - 下次我会为大家发布一个小提琴。以上是关于如何在没有for循环的情况下引用数组的多个索引值?的主要内容,如果未能解决你的问题,请参考以下文章