如何在没有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 循环方式来访问多个无序索引值。 为什么是 048?他们有什么共同点?他们能被什么东西选中吗? 这是关于井字游戏的吗?因为有更简单的方法可以连续检查三个。 【参考方案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 的用例。更多的是forEachfilter @ibrahimmahrir 我在答案中引用了文档。 map 用于从输入数组中返回一个数组 => 所以它只是浪费资源,不应该仅仅用于循环数组,这就是forEach 的用例。 filter 这样写代码会更清晰:var boxArray = $('.box').toArray().filter((x, y) =&gt; 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循环的情况下引用数组的多个索引值?的主要内容,如果未能解决你的问题,请参考以下文章

在没有 for 循环的情况下更新多个文档 MongoDB

Dict()索引(来自输入int)打印相关值

如何在不使用 for 循环的情况下填充二维数组?

如何在 for 循环中包含两个索引值测试条件?

在没有 Python 循环的情况下制作一个单调的 numpy 数组

Howler.js - 从数组/for循环引用和触发文件