Как разбить метод сокращения
Как я могу разбить итерацию на методе сокращения?
для
for (var i = Things.length - 1; i >= 0; i--) {
if(Things[i] <= 0){
break;
}
};
сократить
Things.reduce(function(memo, current){
if(current <= 0){
//break ???
//return; <-- this will return undefined to memo, which is not what I want
}
}, 0)
Ответы
Ответ 1
Разумеется, нет возможности, чтобы встроенная версия reduce
выходила преждевременно.
Но вы можете написать свою собственную версию сокращения, которая использует специальный токен, чтобы идентифицировать, когда цикл должен быть сломан.
var EXIT_REDUCE = {};
function reduce(a, f, result) {
for (let i = 0; i < a.length; i++) {
let val = f(result, a[i], i, a);
if (val === EXIT_REDUCE) break;
result = val;
}
return result;
}
Используйте его так, чтобы суммировать массив, но выйдите, когда вы нажмете 99:
reduce([1, 2, 99, 3], (a, b) => b === 99 ? EXIT_REDUCE : a + b, 0);
> 3
Ответ 2
Вы можете использовать такие функции, как некоторые, и каждый раз, пока вас не волнует возвращаемое значение. каждый разрывается, когда обратный вызов возвращает false, а когда возвращается true:
things.every(function(v, i, o) {
// do stuff
if (timeToBreak) {
return false;
} else {
return true;
}
}, thisArg);
Ответ 3
Вы можете разбить любую итерацию вызова .reduce(), изменив 4-й аргумент функции уменьшения: "array". Нет необходимости в специальной функции сокращения. См. Docs для полного списка параметров .reduce().
Array.prototype.reduce((acc, curr, i, array))//Четвертый аргумент - это массив, который повторяется.
const array = ['9', '91', '95', '96', '99'];
const x = array
.reduce((acc, curr, i, arr) => {
if(i === 2) arr.splice(1);
return acc += curr;
}, '');
console.log('x: ', x); // x: 99195
Почему?:
Единственная причина, по которой я могу думать об этом, а не о многих других представленных решениях, - это то, что вы хотите поддерживать методологию функционального программирования для своего алгоритма, и вы хотите, чтобы наиболее декларативный подход мог это сделать. Если ваша цель состоит в том, чтобы буквально СНИЗИТЬ массив альтернативному не-ложному примитиву (String, Number, Boolean, Symbol), тогда я бы сказал, что это IS действительно лучший подход.
ПОЧЕМУ НЕ?
Там есть целый список аргументов, которые делают для НЕ мутирующих параметров функции, поскольку это плохая практика.
Ответ 4
Вы можете разбить каждый код - и, следовательно, каждую сборку в итераторе - выбросив исключение:
function breakReduceException(value) {
this.value = value
}
try {
Things.reduce(function(memo, current) {
...
if (current <= 0) throw new breakReduceException(memo)
...
}, 0)
} catch (e) {
if (e instanceof breakReduceException) var memo = e.value
else throw e
}
Ответ 5
Array.every может обеспечить очень естественный механизм выхода из итерации высокого порядка.
const product = function(array) {
let accumulator = 1;
array.every( factor => {
accumulator *= factor;
return !!factor;
});
return accumulator;
}
console.log(product([2,2,2,0,2,2]));
// 0
Ответ 6
Не используйте сокращение. Просто перебирайте массив с нормальными итераторами (для и т.д.) И выходите, когда ваше условие выполнено.
Ответ 7
Еще одна простая реализация, с которой я столкнулся при решении одной и той же проблемы:
function reduce(array, reducer, first) {
let result = first || array.shift()
while (array.length > 0) {
result = reducer(result, array.shift())
if (result && result.reduced) {
return result.reduced
}
}
return result
}
Ответ 8
Вы не можете вырваться изнутри выполнения метода сокращения, однако, в зависимости от того, что вы пытались выполнить, вы можете изменить конечный результат с помощью операторов управления и возврата
[1, 1, 1].reduce((a, b) => a + b, 0); // returns 3