web-dev-qa-db-ja.com

JavaScript forループを停止する方法は?

私はこの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を返す必要があります。これを行うためのより良い方法はありますか?

103
frequent

JavaScriptでforループを早期に停止するには、 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)環境にいる場合、このspecificユースケースでは、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 function を配列で使用できます。これは、コールバックが真実の値を返すまでコールバックを呼び出します。

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
    }
});
157
T.J. Crowder

ロジックが正しくありません。常に配列の最後の要素の結果を返します。

remIndex = -1;

for (i = 0; i < remSize.length; i++) {      
    if (remSize[i].size == remData.size) {
        remIndex = i
        break;
    }
}
10
amit_g

代わりにES 2015リリースの一部であるforループを使用します。 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);
}
8