Array each function
требуется быстрая функция для обхода массива, исполняя на каждой итерации функцию. Должна быть возможность прервать цикл.
пока смог реализовать через замыкание. для чего это мне понадобилось, покажу на абстрактных примерах :) порядок обхода совершенно безразличен. я могу сделать reverse, если что. Пример: через замыкание
function each(arr, func) { var al = arr.length, breaked = false; do func( arr[al], al , arr, function(){ breaked=true } ); while ( al-- > 0 && breaked==false ) } var log=[]; each( [1,2,3,"break it",4,5,6,7], function(a,b,c,d){ log.push(a); a==='break it' && d(); } ); alert( "Прошли : \n\n"+ log.join("\n") ) сильно хочется сделать это через метки, но не могу. подскажите, пожалуйста, как лучше всего сделать функцию обхода массива с возможностью прерывания |
Цитата:
|
кажется, сам не стал бы так писать :) да?
Пример: через исключение
var log=[]; try { [1,2,3,"break it",4,5,6,7].forEach ( function(a){ log.push(a); if( a==='break it' ) throw ""; } ); } catch (e) {} alert( "Прошли : \n\n"+ log.join("\n") ) |
Я, наверное, что-то не очень понял...
_log=[]; arr=[1, 2, 3, 4, 5, false, 6, 7]; function each(arr, func) { for (var i=0; i!= arr.length; ++i) { _log.push(arr[i]); if(func(arr[i], i, arr)===false) break; }; }; each(arr, function(a, b, c){if (a===false) return false}); alert(_log); Нет? |
Цитата:
|
И для кроссбраузерности:
Array.prototype.every= Array.prototype.every || function (func, thisObj) { for (var i=0; i!= this.length; ++i) if (i in this && func.call(thisObj, this[i], i, this)) return false; return true; }; Ну и some так же... |
Цитата:
|
Цитата:
Как это типично...)) |
Поправил, виноват...
|
Ещё нужна проверка i in this, и callback функция не обязана возвращать строго false.
http://alljs.ru/s/files/Array.js |
Цитата:
|
Элементы в массиве могут быть пропущены.
var a = [1, 2, , , , 3]; |
Понял)) Спасибо))
|
В моздоках фигурирует такая:
if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(searchElement /*, fromIndex */) { "use strict"; if (this === void 0 || this === null) throw new TypeError(); var t = Object(this); var len = t.length >>> 0; if (len === 0) return -1; var n = 0; if (arguments.length > 0) { n = Number(arguments[1]); if (n !== n) // shortcut for verifying if it's NaN n = 0; else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) n = (n > 0 || -1) * Math.floor(Math.abs(n)); } if (n >= len) return -1; var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); for (; k < len; k++) { if (k in t && t[k] === searchElement) return k; } return -1; }; } Мот кто объяснит зачем монипуляции до цикла? |
Не особо-то она правильная, по-моему... Хотя не мне об этом говорить))
|
Вроде в доках заявлена, как эквивалент встроенной.
|
Цитата:
|
Ну я начал копаться в Array.js потом перешёл на доки от мозилы. Там вроде для всех новых методов массива есть эквиваленты. Ну индексоф и попался...
|
Цитата:
видно, не так это просто сделать :) if( typeof Array.prototype.forEach === 'undefined' ) Array.prototype.forEach = function( func ){ var arrl, arr = this.reverse(); do if (arrl in arr) func( arr[arrl], arrl, arr ); while( arrl -= 1 > 0 ); } // test .. var log=[]; function each( array, func ){ try { array.forEach( func ) } catch(e) {}; } each( [1,2,3,"break it",4,5,6,7], function(a){ log.push(a); if( a==='break it' ) throw ""; } ); alert( "Прошли : \n\n"+ log.join("\n") ); |
Цитата:
|
какая разница между forEach и every, например, в моей задаче (прерывание) ?
даже передают обе одинаковые аргументы - член массива, ключ, весь массив |
melky,
ещё один неправильно реализующий стандартные функции. |
if( typeof Array.prototype.forEach === 'undefined' ) Array.prototype.forEach = function (iterator, context) { for (var i = 0, length = this.length >>> 0; i < length; i++) { if (i in this) iterator.call(context, this[i], i, this); } } Prototype.js я просто с ума от изящества но зачем делать так ? this.length >>> 0 Пример: это же Math.floor
alert ( [ "_______","|examples :","_______", "|9 >>> 0", "=> "+ (9 >>> 0), "| 9.8 >>> 0", "=> "+ (9.8 >>> 0), "_______"].join("\n") ); можно было и так, Kolyaj :) if( typeof Array.prototype.forEach === 'undefined' ) Array.prototype.forEach = function(fn, ctx) { for (var i = 0, l = this.length; i < l; i++) if (i in this) fn.call(ctx, this[i], i, this); }; ну а прерывать как? через метание ? |
|
melky,
а зачем ты мой ник приписал к функции, к которой я не имею никакого отношения? |
да ладно. какая разница?
|
Непонятен смысл твоего сравнения. Ты сравниваешь плохую реализацию (throw) с неправильной (i--).
|
это не реализация функции по-умолчанию, а написание своей, с возможностью прервать её, Kolyaj
сколько способов реализации знаю, так и написал :) |
использовать исключения плохо
к тому же, они прерывают только 1 цикл, а сразу два вложенных не умеют. и вообще, использовать исключения в штатной ситуации - надо быть совсем упоротым. чтобы прерывать нужно передавать функцию прерывания в колбэк. но лучше не использовать для этого замыкания, а сделать итератор |
Цитата:
alert([typeof '10', typeof ('10' >>> 0)]) во-вторых, для того чтобы предотвратить выход за пределы максимально допустимого диапазона чисел. |
Часовой пояс GMT +3, время: 21:07. |