Jquery each - остановить цикл и вернуть объект

Кто-нибудь может сказать мне, почему цикл не остановился после записи 5?

http://jsbin.com/ucuqot/edit#preview


$(document).ready(function()
{
  someArray = new Array();
  someArray[0] = 't5';
  someArray[1] = 'z12';
  someArray[2] = 'b88';
  someArray[3] = 's55';
  someArray[4] = 'e51';
  someArray[5] = 'o322';
  someArray[6] = 'i22';
  someArray[7] = 'k954';  

  var test =  findXX('o322');   

});

function findXX(word)
{  
  $.each(someArray, function(i)
  {
    $('body').append('-> '+i+'<br />');
    if(someArray[i] == 'someArray')
    {
      return someArray[i]; //<--- did not stop the loop!
    }   
  });  
}

person user970727    schedule 22.11.2011    source источник
comment
Вы уверены, что это правда, если (someArray [i] == 'someArray')   -  person zaoudis    schedule 22.11.2011
comment
Я думаю, что это условие (someArray [i] == 'someArray') должно быть (someArray [i] == word)   -  person Irfan    schedule 22.11.2011
comment
@ user970727 посмотри на мой ответ. он использует интегрированную функцию (i, n) в каждой команде   -  person Royi Namir    schedule 22.11.2011


Ответы (6)


Потому что, когда вы используете оператор return внутри цикла each, значение "не ложное" будет действовать как continue, тогда как false будет действовать как break. Вам нужно будет вернуть false из функции each. Что-то вроде этого:

function findXX(word) {
    var toReturn; 
    $.each(someArray, function(i) {
        $('body').append('-> '+i+'<br />');
        if(someArray[i] == word) {
            toReturn = someArray[i];
            return false;
        }   
    }); 
    return toReturn; 
}

Из документов:

Мы можем прервать цикл $ .each () на определенной итерации, заставив функцию обратного вызова вернуть false. Возврат non-false аналогичен оператору continue в цикле for; он немедленно перейдет к следующей итерации.

person James Allardice    schedule 22.11.2011
comment
почему вы не используете интегрированный function(i,n)? - person Royi Namir; 22.11.2011
comment
Поскольку я просто использовал код, опубликованный в вопросе, и изменил return. - person James Allardice; 22.11.2011
comment
@ user970727 - В этом примере у вас вообще нет оператора return в цикле each ... Вот обновленный пример: jsbin.com/ucuqot/5/edit - person James Allardice; 22.11.2011
comment
@JamesAllardice у меня не сработал при return = false; он нормально выходит из цикла, но позже распространяется на оператор return toReturn; где в моем случае я возвращаю true. поэтому true всегда возвращается, даже если выполняется return = false - person pavan kumar; 23.03.2017
comment
Почему так? можно подумать, возврат некоторого значения будет означать выход из цикла. - person kiwicomb123; 31.03.2017

здесь :

http://jsbin.com/ucuqot/3/edit

function findXX(word)
{  
  $.each(someArray, function(i,n)
  {
    $('body').append('-> '+i+'<br />');
    if(n == word)
    {
      return false;
    }   
  });  
}
person Royi Namir    schedule 22.11.2011

модифицированная $.each функция

$.fn.eachReturn = function(arr, callback) {
   var result = null;
   $.each(arr, function(index, value){
       var test = callback(index, value);
       if (test) {
           result = test;
           return false;
       }
   });
   return result ;
}

он прервет цикл на не ложном / непустом результате и вернет его обратно, поэтому в вашем случае это будет

return $.eachReturn(someArray, function(i){
    ...
person Peter    schedule 09.02.2016

Попробуй это ...

  someArray = new Array();
  someArray[0] = 't5';
  someArray[1] = 'z12';
  someArray[2] = 'b88';
  someArray[3] = 's55';
  someArray[4] = 'e51';
  someArray[5] = 'o322';
  someArray[6] = 'i22';
  someArray[7] = 'k954';  

  var test =  findXX('o322'); 
  console.log(test);



function findXX(word)
{  
  for(var i in someArray){


    if(someArray[i] == word)
    {
      return someArray[i]; //<---  stop the loop!
    }   
  }
}
person sangeeth kumar    schedule 05.05.2015

«Мы можем прервать цикл $ .each () на определенной итерации, заставив функцию обратного вызова вернуть false. Возврат не false аналогичен оператору continue в цикле for; он немедленно перейдет к следующей итерации».

из http://api.jquery.com/jquery.each/

Да, это старое НО, ТОЛЬКО, чтобы ответить на вопрос, это может быть немного проще:

function findXX(word) {
  $.each(someArray, function(index, value) {
    $('body').append('-> ' + index + ":" + value + '<br />');
    return !(value == word);
  });
}
$(function() {
  someArray = new Array();
  someArray[0] = 't5';
  someArray[1] = 'z12';
  someArray[2] = 'b88';
  someArray[3] = 's55';
  someArray[4] = 'e51';
  someArray[5] = 'o322';
  someArray[6] = 'i22';
  someArray[7] = 'k954';
  findXX('o322');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

A bit more with comments:

function findXX(myA, word) {
  let br = '<br />';//create once
  let myHolder = $("<div />");//get a holder to not hit DOM a lot
  let found = false;//default return
  $.each(myA, function(index, value) {
    found = (value == word);
    myHolder.append('-> ' + index + ":" + value + br);
    return !found;
  });
  $('body').append(myHolder.html());// hit DOM once
  return found;
}
$(function() {
  // no horrid global array, easier array setup;
  let someArray = ['t5', 'z12', 'b88', 's55', 'e51', 'o322', 'i22', 'k954'];
  // pass the array and the value we want to find, return back a value
  let test = findXX(someArray, 'o322');
  $('body').append("<div>Found:" + test + "</div>");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

ПРИМЕЧАНИЕ: здесь может лучше подойти массив .includes() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes

Или просто .find(), чтобы получить этот https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find

person Mark Schultheiss    schedule 01.05.2019

Вместо установки флага было бы более элегантно использовать JavaScript Array.prototype.find для поиска соответствующего элемента в массиве. Цикл завершится, как только обратный вызов вернет истинное значение, и значение массива во время этой итерации будет возвращаемым значением вызова .find:

function findXX(word) {
    return someArray.find((item, i) => {
        $('body').append('-> '+i+'<br />');
        return item === word;
    }); 
}

const someArray = new Array();
someArray[0] = 't5';
someArray[1] = 'z12';
someArray[2] = 'b88';
someArray[3] = 's55';
someArray[4] = 'e51';
someArray[5] = 'o322';
someArray[6] = 'i22';
someArray[7] = 'k954';

var test = findXX('o322');
console.log('found word:', test);

function findXX(word) {
  return someArray.find((item, i) => {
    $('body').append('-> ' + i + '<br />');
    return item === word;
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

person CertainPerformance    schedule 16.09.2020