Как остановить цикл 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
    }
});

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;
    }
}

0

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

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

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

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


1
Это не дает ответа на вопрос заголовка: How to stop a JavaScript for loop?Это делает ответ Есть ли лучший способ вернуть индекс матча / -1 , если ни один .
— глиняный кувшин
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.