Как остановить цикл JavaScript for?

128

Я использую этот JavaScript для перебора массива и нахождения соответствующего элемента массива:

var remSize = [], 
    szString, remData, remIndex, i;

for (i = 0; i < remSize.length; i++) {      
    // I'm looking for the index i, when the condition is true
    remSize[i].size == remData.size ? remIndex = i : remIndex = -1;     
}

Массив содержит эти «размеры»: ["34", "36", "38"...].

remData.size это "размер", который я ищу (например, "36").

Мне нужно вернуть индекс, iесли размер, который я ищу, находится в индексе. В противном случае мне нужно вернуться -1. Есть лучший способ сделать это?

частый
источник

Ответы:

194

Чтобы остановить forцикл на ранней стадии в JavaScript, вы используете break:

var remSize = [], 
    szString,
    remData,
    remIndex,
    i;

/* ...I assume there's code here putting entries in `remSize` and assigning something to `remData`... */

remIndex = -1; // Set a default if we don't find it
for (i = 0; i < remSize.length; i++) {      
     // I'm looking for the index i, when the condition is true
     if (remSize[i].size === remData.size) {
          remIndex = i;
          break;       // <=== breaks out of the loop early
     }
}

Если вы находитесь в среде ES2015 (также известной как ES6), для этого конкретного варианта использования вы можете использовать Array#findIndex(чтобы найти индекс записи) или Array#find(чтобы найти саму запись), оба из которых могут быть объединены / полифиллированы:

var remSize = [], 
    szString,
    remData,
    remIndex;

/* ...I assume there's code here putting entries in `remSize` and assigning something to `remData`... */

remIndex = remSize.findIndex(function(entry) {
     return entry.size === remData.size;
});

Array#find:

var remSize = [], 
    szString,
    remData,
    remEntry;

/* ...I assume there's code here putting entries in `remSize` and assigning something to `remData`... */

remEntry = remSize.find(function(entry) {
     return entry.size === remData.size;
});

Array#findIndexостанавливает первый раз, когда обратный вызов возвращает истинное значение, возвращая индекс для этого вызова обратному вызову; он возвращается, -1если обратный вызов никогда не возвращает истинное значение. Array#findтакже останавливается, когда находит то, что вы ищете, но возвращает запись, а не ее индекс (или undefinedесли обратный вызов никогда не возвращает истинное значение).

Если вы используете среду, совместимую с ES5 (или прокладку ES5), вы можете использовать новую someфункцию для массивов, которая вызывает обратный вызов, пока обратный вызов не вернет истинное значение:

var remSize = [], 
    szString,
    remData,
    remIndex;

/* ...I assume there's code here putting entries in `remSize` and assigning something to `remData`... */

remIndex = -1; // <== Set a default if we don't find it
remSize.some(function(entry, index) {
    if (entry.size === remData.size) {
        remIndex = index;
        return true; // <== Equivalent of break for `Array#some`
    }
});

Если вы используете jQuery, вы можете использовать jQuery.eachдля цикла по массиву; это будет выглядеть так:

var remSize = [], 
    szString,
    remData,
    remIndex;

/* ...I assume there's code here putting entries in `remSize` and assigning something to `remData`... */

remIndex = -1; // <== Set a default if we don't find it
jQuery.each(remSize, function(index, entry) {
    if (entry.size === remData.size) {
        remIndex = index;
        return false; // <== Equivalent of break for jQuery.each
    }
});
TJ Crowder
источник
1
использование оператора return - хороший подход. Спасибо @TJ Crowder
techloris_109
@TJ Crowder, какое утверждение является хорошим подходом: вернуть false или break?
Ильяс
3
@Ilyaskarim: вы используете тот, который подходит для используемой конструкции ( breakв forцикле, return falseв jQuery.each, return trueв some, ...).
TJ Crowder
13

Вместо этого используйте цикл for of, который является частью выпуска ES2015. В отличие от forEach, мы можем использовать return, break и continue. См. Https://hacks.mozilla.org/2015/04/es6-in-depth-iterators-and-the-for-of-loop/

let arr = [1,2,3,4,5];
for (let ele of arr) {
  if (ele > 3) break;
  console.log(ele);
}
Срини Картикеян
источник
хорошее использование es6, я думаю, что это один из лучших ответов здесь
Эмад Салах
В самом деле, я бы сказал, что это лучший ответ здесь - самый изящный способ сделать это («самый лаконичный и прямой синтаксис для циклического перебора элементов массива», как говорится в ответе Mozilla Hacks по ссылке). Мы должны отплатить за всю тяжелую работу, проделанную над ES6, используя его новые функции везде, где мы можем (и извлекать выгоду из этого процесса).
Велоджет
10

Логика неверная. Он всегда будет возвращать результат последнего элемента в массиве.

remIndex = -1;

for (i = 0; i < remSize.length; i++) {      
    if (remSize[i].size == remData.size) {
        remIndex = i
        break;
    }
}
amit_g
источник
0

Я знаю, что это немного устарело, но вместо того, чтобы перебирать массив с помощью цикла for, было бы намного проще использовать метод <array>.indexOf(<element>[, fromIndex])

Он просматривает массив, находя и возвращая первый индекс значения. Если значение не содержится в массиве, возвращается -1.

<array>это массив для просмотра, <element>это значение, которое вы ищете, и [fromIndex]это индекс, с которого следует начать (по умолчанию 0).

Надеюсь, это поможет уменьшить размер вашего кода!

JMoore2007
источник
1
Это не дает ответа на вопрос заголовка: How to stop a JavaScript for loop?Это делает ответ Есть ли лучший способ вернуть индекс матча / -1 , если ни один .
глиняный кувшин