【问题标题】:How to reference multiple index values of an array without a for-loop?如何在没有for循环的情况下引用数组的多个索引值?
【发布时间】: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?他们有什么共同点?他们能被什么东西选中吗?
  • 这是关于井字游戏的吗?因为有更简单的方法可以连续检查三个。

标签: javascript jquery arrays for-loop


【解决方案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 的逗号分隔吗?我希望它确保所有这三个索引值都具有“点击”类。道歉 - 下次我会为大家发布一个小提琴。
        猜你喜欢
        • 1970-01-01
        • 2018-04-13
        • 1970-01-01
        • 2019-07-02
        • 2021-11-18
        • 2013-02-16
        • 2021-01-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多