Короткое замыкание Array.forEach как вызов прерывания

Вы не можете восстановить базу данных (или прикрепить), созданную в верхней версии, в более низкую версию.

выберите «Схема и данные» - , если вы хотите взять обе вещи в файл сценария резервного копирования , выберите «Только схема» - , если нужна только схема.

blockquote>

Да, теперь вы сделали с помощью Create Script с помощью схемы и данных базы данных.

1303
задан Alexander Abakumov 21 September 2018 в 14:47
поделиться

16 ответов

Нет встроенной возможности сломать в forEach . Чтобы прервать выполнение, вам нужно будет вызвать какое-то исключение. например.

 var BreakException = {}; попробуйте {[1, 2, 3] .forEach (function (el) {console.log (el); if (el === 2) throw BreakException;}); } catch (e) {if (e! == BreakException) throw e; } 

Исключения JavaScript не очень красивы. Традиционный цикл for может быть более подходящим, если вам действительно нужно break внутри него.

Используйте Array # some

Вместо этого используйте Array # some :

  [1, 2, 3] .some (function (el) {console.log (el); return el === 2;}); 

Это работает, потому что some возвращает true , как только любой из обратных вызовов, выполняемых в порядке массива, возвращает true , прерывая выполнение остальных.

some , его обратный every (который остановится на return false ) и forEach - все методы ECMAScript Fifth Edition, которые потребуют будут добавлены в Array.prototype в браузерах, в которых они отсутствуют.

1949
ответ дан 22 November 2019 в 20:19
поделиться

Вы можете следовать приведенному ниже коду, который работает для меня:

 var     loopStop = false;
YOUR_ARRAY.forEach(function loop(){
    if(loopStop){ return; }
    if(condition){ loopStop = true; }
});
0
ответ дан Ian Clark 21 September 2018 в 14:47
поделиться
var Book = {"Titles":[                          
    {
    "Book3" : "BULLETIN 3"
    }   
    ,
    {
    "Book1" : "BULLETIN 1"
    }
    ,
    {
    "Book2" : "BULLETIN 2"
    }    
]}

var findbystr = function(str) { 
    var return_val;
    Book.Titles.forEach(function(data){ 
        if(typeof data[str] != 'undefined')
        {
            return_val = data[str];
        } 
    }, str) 

    return return_val;
}

book = findbystr('Book1');
console.log(book);
-3
ответ дан Samuel Gray 21 September 2018 в 14:47
поделиться

Еще один подход

        var wageType = types.filter(function(element){
            if(e.params.data.text == element.name){ 
                return element;
            }
        });
        console.dir(wageType);
1
ответ дан Harry Bosh 21 September 2018 в 14:47
поделиться

Это цикл for, но он поддерживает ссылку на объект в цикле, как и forEach (), но вы можете выйти из него.

var arr = [1,2,3];
for (var i = 0, el; el = arr[i]; i++) {
    if(el === 1) break;
}
3
ответ дан jamos 21 September 2018 в 14:47
поделиться

Согласен с @bobince, проголосовал.

Кроме того, к вашему сведению:

Prototype.js имеет что-то для этой цели:

<script type="text/javascript">
  $('a').each(function(el, idx) {
    if ( /* break condition */ ) throw $break;
    // do something
  });
</script>

$break будет перехватываться и обрабатываться внутри Prototype.js, ломая «каждый» цикл, но не генерирует внешние ошибки.

Подробнее см. Prototype.JS API .

У jQuery также есть способ, просто верните false в обработчике, чтобы прервать цикл раньше:

<script type="text/javascript">
  jQuery('a').each( function(idx) {
    if ( /* break condition */ ) return false;
    // do something

  });
</script>

Подробности см. В jQuery API .

0
ответ дан Dmitri Sologoubenko 21 September 2018 в 14:47
поделиться

Если вы хотите сохранить синтаксис forEach, это способ повысить его эффективность (хотя и не так хорошо, как обычный цикл for). Немедленно проверьте переменную, которая знает, хотите ли вы выйти из цикла.

В этом примере используется анонимная функция для создания области функции вокруг forEach, которая необходима для хранения информации done .

(function(){
    var element = document.getElementById('printed-result');
    var done = false;
    [1,2,3,4].forEach(function(item){
        if(done){ return; }
        var text = document.createTextNode(item);
        element.appendChild(text);
        if (item === 2){
          done = true;
          return;
        }
    });
})();
<div id="printed-result"></div>

Мои два цента.

1
ответ дан Justus Romijn 21 September 2018 в 14:47
поделиться

Еще одна концепция, которую я придумал:

function forEach(array, cb) {
  var shouldBreak;
  function _break() { shouldBreak = true; }
  for (var i = 0, bound = array.length; i < bound; ++i) {
    if (shouldBreak) { break; }
    cb(array[i], i, array, _break);
  }
}

// Usage

forEach(['a','b','c','d','e','f'], function (char, i, array, _break) {
  console.log(i, char);
  if (i === 2) { _break(); }
});
3
ответ дан c24w 21 September 2018 в 14:47
поделиться

Это как раз то, что я придумал, чтобы решить проблему ... Я почти уверен, что это решает проблему, с которой столкнулся оригинальный аскер:

Array.prototype.each = function(callback){
    if(!callback) return false;
    for(var i=0; i<this.length; i++){
        if(callback(this[i], i) == false) break;
    }
};

И тогда вы бы назвали это, используя :

var myarray = [1,2,3];
myarray.each(function(item, index){
    // do something with the item
    // if(item != somecondition) return false; 
});

Возвращение false внутри функции обратного вызова приведет к прерыванию. Дайте мне знать, если это не сработает.

3
ответ дан tennisgent 21 September 2018 в 14:47
поделиться

Из вашего примера кода выглядит, что Array.prototype.find - это то, что вы ищете: Array.prototype.find () и Array.prototype.findIndex ()

[1, 2, 3].find(function(el) {
    return el === 2;
}); // returns 2
17
ответ дан Mahdi 21 September 2018 в 14:47
поделиться

К сожалению, в этом случае будет намного лучше, если вы не используете forEach. Вместо этого используйте обычный цикл for, и теперь он будет работать точно так, как вы ожидаете.

var array = [1, 2, 3];
for (var i = 0; i < array.length; i++) {
  if (array[i] === 1){
    break;
  }
}
59
ответ дан Weston Ganger 21 September 2018 в 14:47
поделиться

Вы можете использовать каждый метод:

[1,2,3].every(function(el) {
    return !(el === 1);
});

ES6

[1,2,3].every( el => el !== 1 )

для использования в старых браузерах:

if (!Array.prototype.every)
{
  Array.prototype.every = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this &&
          !fun.call(thisp, this[i], i, this))
        return false;
    }

    return true;
  };
}

больше подробности здесь .

184
ответ дан Rich 21 September 2018 в 14:47
поделиться

Краткий ответ: используйте для этого for...break или измените код, чтобы избежать нарушения forEach. Не используйте .some() или .every() для эмуляции for...break. Перепишите свой код, чтобы избежать цикла for...break, или используйте for...break. Каждый раз, когда вы используете эти методы в качестве альтернативы for...break, Бог убивает котенка.

Длинный ответ:

.some() и .every() оба возвращают значение boolean, .some() возвращает true, если есть какой-либо элемент, для которого переданная функция возвращает true, каждый возвращает false, если существует какой-либо элемент, для которого переданная функция возвращает false. Вот что означают эти функции. Использование функций для того, что они не имеют в виду, гораздо хуже, чем использование таблиц для разметки вместо CSS, потому что это расстраивает всех, кто читает ваш код.

Кроме того, единственный возможный способ использовать эти методы в качестве альтернативы for...break - создавать побочные эффекты (изменять некоторые переменные вне функции обратного вызова .some()), и это мало чем отличается от for...break.

]

Таким образом, использование .some() или .every() в качестве альтернативы цикла for...break не лишено побочных эффектов, это не намного чище, чем for...break, это расстраивает, так что это не лучше.

Вы всегда можете переписать свой код, чтобы в for...break не было необходимости. Вы можете отфильтровать массив с помощью .filter(), вы можете разделить массив с помощью .slice() и т. Д., А затем использовать .forEach() или .map() для этой части массива.

8
ответ дан Max 21 September 2018 в 14:47
поделиться

решение для карты очень похоже на пример OP. Относительно производительности, для циклов являются самыми быстрыми, но карта так же сжата как forEach, и для "не слишком много объектов", это не будет иметь значения.

[1,2,3].map(function(el) {
    if(el === 1) return
})
-2
ответ дан 22 November 2019 в 20:19
поделиться

Нашел это решение на другом сайте. Вы можете обернуть forEach в сценарий try / catch.

if(typeof StopIteration == "undefined") {
 StopIteration = new Error("StopIteration");
}

try {
  [1,2,3].forEach(function(el){
    alert(el);
    if(el === 1) throw StopIteration;
  });
} catch(error) { if(error != StopIteration) throw error; }

Более подробно здесь: http://dean.edwards.name/weblog/2006/07/enum/

4
ответ дан 22 November 2019 в 20:19
поделиться

Рассмотрите возможность использования метода jquery each, поскольку он позволяет возвращать false внутри функции обратного вызова:

$.each(function(e, i) { 
   if (i % 2) return false;
   console.log(e)
})

Библиотеки Lodash также предоставляют takeWhile метод, который может быть связан с map/reduce/fold и т.д.:

var users = [
  { 'user': 'barney',  'active': false },
  { 'user': 'fred',    'active': false },
  { 'user': 'pebbles', 'active': true }
];

_.takeWhile(users, function(o) { return !o.active; });
// => objects for ['barney', 'fred']

// The `_.matches` iteratee shorthand.
_.takeWhile(users, { 'user': 'barney', 'active': false });
// => objects for ['barney']

// The `_.matchesProperty` iteratee shorthand.
_.takeWhile(users, ['active', false]);
// => objects for ['barney', 'fred']

// The `_.property` iteratee shorthand.
_.takeWhile(users, 'active');
// => []
25
ответ дан 22 November 2019 в 20:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: