[javascript] reduce () 메서드를 조기에 중단하는 방법은 무엇입니까?

reduce()메서드 반복을 어떻게 끊을 수 있습니까?

for:

for (var i = Things.length - 1; i >= 0; i--) {
  if(Things[i] <= 0){
    break;
  }
};

reduce()

Things.reduce(function(memo, current){
  if(current <= 0){
    //break ???
    //return; <-- this will return undefined to memo, which is not what I want
  }
}, 0)



답변

최신 정보

일부 해설자는 .reduce()논리 내부를 조기에 중단하기 위해 원래 배열이 변형되고 있다는 좋은 지적을합니다 .

따라서 후속 단계 를 호출하기 전에 a를 추가 하여 원래 배열의 복사본을 생성 하여 대답을 약간 수정했습니다 .
참고 : 동일한 작업을 수행하는 유사한 작업은 (덜 명시 적) 및 분산 연산자 ( 약간 성능이 낮음 )입니다. 이들 모두는 전체 런타임 + 1 * (O (1))에 선형 시간의 추가 상수 계수를 추가합니다..slice(0).reduce()slice()[...array]

사본은 반복에서 방출을 유발하는 최종 돌연변이로부터 원래 배열을 보존하는 역할을합니다.

const array = ['9', '91', '95', '96', '99'];
const x = array
    .slice(0)                         // create copy of "array" for iterating
    .reduce((acc, curr, i, arr) => {
       if (i === 2) arr.splice(1);    // eject early by mutating iterated copy
       return (acc += curr);
    }, '');

console.log("x: ", x, "\noriginal Arr: ", array);
// x:  99195
// original Arr:  [ '9', '91', '95', '96', '99' ]


낡은

reduce 함수의 네 번째 인수 인 “array”를 변경하여 .reduce () 호출의 반복을 중단 할 수 있습니다. 사용자 정의 감소 기능이 필요하지 않습니다. 전체 매개 변수 목록은 문서 를 참조하세요 .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);  // eject early
    return acc += curr;
  }, '');
console.log('x: ', x);  // x:  99195

왜?:

제시된 다른 많은 솔루션 대신 이것을 사용하는 유일한 이유는 알고리즘에 대한 함수형 프로그래밍 방법론을 유지하고이를 달성하기 위해 가능한 가장 선언적인 접근 방식을 원하는 경우입니다. 전체 목표가 문자 그대로 배열을 거짓이 아닌 대체 기본 형식 (문자열, 숫자, 부울, 기호)으로 줄이는 것이라면 이것이 실제로 가장 좋은 방법이라고 주장합니다.

왜 안돼?

그것은 나쁜 습관이기 때문에 함수 매개 변수를 변경하지 않기 위해 만드는 전체 인수 목록이 있습니다.


답변

감소를 사용하지 마십시오. 일반 반복자 (for 등)로 배열을 반복하고 조건이 충족되면 중단하십시오.


답변

반환 값에 신경 쓰지 않는 한 someevery 와 같은 함수를 사용할 수 있습니다 . 모든 콜백 false를 반환 휴식, 일부 사실 반환 할 때 :

things.every(function(v, i, o) {
  // do stuff 
  if (timeToBreak) {
    return false;
  } else {
    return true;
  }
}, thisArg);


답변

물론의 내장 버전을 reduce조기에 종료 할 수있는 방법은 없습니다 .

그러나 특별한 토큰을 사용하여 루프가 중단되어야하는시기를 식별하는 자체 버전의 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


답변

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


답변

예외를 발생시켜 모든 코드 (따라서 반복기의 모든 빌드)를 중단 할 수 있습니다.

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
}


답변

는 AS promise의 가지고 resolvereject콜백 인수를, 내가 만든 reduce과 해결 기능 break콜백 인수를. reduce첫 번째 인수 가 작업 할 배열이라는 점을 제외하면 네이티브 메서드 와 동일한 인수를 모두 사용합니다 (원숭이 패치 방지). 세 번째 [2] initialValue인수는 선택 사항입니다. function감속기에 대해서는 아래 스 니펫을 참조하십시오 .

var list = ["w","o","r","l","d"," ","p","i","e","r","o","g","i"];

var result = reducer(list,(total,current,index,arr,stop)=>{
  if(current === " ") stop(); //when called, the loop breaks
  return total + current;
},'hello ');

console.log(result); //hello world

function reducer(arr, callback, initial) {
  var hasInitial = arguments.length >= 3;
  var total = hasInitial ? initial : arr[0];
  var breakNow = false;
  for (var i = hasInitial ? 0 : 1; i < arr.length; i++) {
    var currentValue = arr[i];
    var currentIndex = i;
    var newTotal = callback(total, currentValue, currentIndex, arr, () => breakNow = true);
    if (breakNow) break;
    total = newTotal;
  }
  return total;
}

다음은 reducer배열 method수정 스크립트입니다.

Array.prototype.reducer = function(callback,initial){
  var hasInitial = arguments.length >= 2;
  var total = hasInitial ? initial : this[0];
  var breakNow = false;
  for (var i = hasInitial ? 0 : 1; i < this.length; i++) {
    var currentValue = this[i];
    var currentIndex = i;
    var newTotal = callback(total, currentValue, currentIndex, this, () => breakNow = true);
    if (breakNow) break;
    total = newTotal;
  }
  return total;
};

var list = ["w","o","r","l","d"," ","p","i","e","r","o","g","i"];

var result = list.reducer((total,current,index,arr,stop)=>{
  if(current === " ") stop(); //when called, the loop breaks
  return total + current;
},'hello ');


console.log(result);