숫자 배열의 합을 찾는 방법


808

배열이 주어지면 [1, 2, 3, 4]요소의 합계를 어떻게 찾을 수 있습니까? (이 경우 합계는입니다 10.)

$.each유용 하다고 생각 했지만 구현 방법을 잘 모르겠습니다.



18
@ tereško Google에 대한 의지가 Stackoverflow의 유효한 근거가 아닙니다. 질문이 제대로 검색되지 않았다고 생각되면 공감하십시오. (또한 답변으로 판단-이것은 고도로 공세 된 나쁜 관행 (평가)을 포함하여 많은 가능한 해결책을 가진 논란의 여지가있는 주제 인 것 같습니다.)
Trilarion

8
참고 : 여기의 대부분의 대답은 본질적으로 compute입니다 a[0] + a[1] + .... 배열에 숫자가 아닌 요소가 있으면 문자열 연결로 바뀔 수 있습니다. 예 ['foo', 42].reduce((a,b)=>a+b, 0) === "0foo42".
Beni Cherniavsky-Paskin

내장 된 감속기가 없으므로 Array.reduce에 공급할 수 있습니까? 같은 생각 [1,2,3].reduce(Math.sum).
Phil

답변:


542

권장 (기본값으로 줄임)

Array.prototype.reduce 는 현재 요소 값을 이전 요소 값의 합계에 더하여 배열을 반복하는 데 사용할 수 있습니다.

console.log(
  [1, 2, 3, 4].reduce((a, b) => a + b, 0)
)
console.log(
  [].reduce((a, b) => a + b, 0)
)

기본값없이

TypeError가 발생합니다

console.log(
  [].reduce((a, b) => a + b)
)

ES6의 화살표 기능 이전

console.log(
  [1,2,3].reduce(function(acc, val) { return acc + val; }, 0)
)

console.log(
  [].reduce(function(acc, val) { return acc + val; }, 0)
)

숫자가 아닌 입력

숫자가 아닌 입력이 가능한 경우 처리 할 수 ​​있습니까?

console.log(
  ["hi", 1, 2, "frog"].reduce((a, b) => a + b)
)

let numOr0 = n => isNaN(n) ? 0 : n

console.log(
  ["hi", 1, 2, "frog"].reduce((a, b) => 
    numOr0(a) + numOr0(b))
)

권장되지 않는 위험한 평가 사용

eval 을 사용 하여 JavaScript 코드의 문자열 표현을 실행할 수 있습니다 . Array.prototype.join 함수를 사용하여 배열을 문자열로 변환하면 [1,2,3]이 "1 + 2 + 3"으로 변경되어 6으로 평가됩니다.

console.log(
  eval([1,2,3].join('+'))
)

//This way is dangerous if the array is built
// from user input as it may be exploited eg: 

eval([1,"2;alert('Malicious code!')"].join('+'))

물론 경고를 표시하는 것이 일어날 수있는 최악의 일은 아닙니다. 내가 이것을 포함시킨 유일한 이유는 그것이 명확하지 않다고 생각하기 때문에 Ortund의 질문에 대한 답변입니다.


8
당신은이 마법이 오랜 세월이 지난 후 reduce()단순한 색인 for()루프 보다 25-30 % 느리다는 것을 알고 있습니까? jsperf.com/reduce-vs-loop/4
tevemadar

그런데 숫자가 "0"이면 문제가 발생합니다. 어떤 이유로 든 문자열로 해석 될 수 있습니다. 1 * a + 1 * b를 추가하면 나를 위해 일했습니다. 속도에 관해서는, 이것은 쓰기가 더 쉬웠고 속도에 신경 쓰지 않습니다
Peter Kay

1179

에서 리스프 에 대해 정확하게 작업 할 수 this'd reduce. 이런 종류의 코드가 표시됩니다.

(reduce #'+ '(1 2 3)) ; 6

다행히도 JavaScript에는 우리도 있습니다 reduce! 불행히도, +함수가 아닌 연산자입니다. 그러나 우리는 그것을 예쁘게 만들 수 있습니다! 여기를보십시오 :

const sum = [1, 2, 3].reduce(add,0); // with initial value to avoid when the array is empty

function add(accumulator, a) {
    return accumulator + a;
}

console.log(sum); // 6

예쁘지 않습니까? :-)

더 나은! ECMAScript 2015 (일명 ECMAScript 6 )를 사용하는 경우 다음 과 같이 될 수 있습니다.

const sum = [1, 2, 3].reduce((partial_sum, a) => partial_sum + a,0); 
console.log(sum); // 6

28
우리 모두 ES2015를 사용한다고 가정하면 덜 장황하게 만들 수 있습니다.[1, 2, 3].reduce((a,b)=>a+b)
Denys Séguret

1
함수 (a, b)를 사용하여 reduce의 실행 시간이 수동 반복 및 합산과 비교 가능한지 또는 상당한 오버 헤드가 포함되어 있는지 궁금합니다.
Trilarion

1
답변은 실제로 링크 된 페이지에서 찾을 수 있다고 언급 할 가치가 있다고 생각합니다. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Alex Cohn

2
배열에 몇 가지 메소드를 추가합니다.Array.prototype.sum = function() { return this.reduce((a,b) => a+b, 0); } Array.prototype.avg = function() { return this.reduce((a,b) => a+b, 0)/this.length; }
pilat

2
@Black 배열을 단일 값으로 줄입니다.
Florian Margaine

204

왜 줄이지 않습니까? 일반적으로 약간의 카운터 직관적이지만 합계를 찾기 위해 사용하는 것은 매우 간단합니다.

var a = [1,2,3];
var sum = a.reduce(function(a, b) { return a + b; }, 0);

3
IE8은 그것을 지원하지 않으며 jQuery가 그것을 추가하려고하는 것처럼 보이지 않습니다. 그러나 프로토 타입에는 있습니다.
Ishmael Smyrnow

4
@Ishmael, UnderscoreJS를 사용할 수 있습니다. UnderscoreJS는 사용 가능한 경우 브라우저 구현으로 돌아가거나 그렇지 않으면 자체 구현합니다.
Pablo Diaz

3
반 직관이란 무엇입니까 reduce()?
canon

3
@ s4nji은 Array.prototype.reduce() 감소 하나의 리턴 값에 배열.
캐논

6
@ s4nji ... 소스를 줄이지 않는 한-이 경우 필수 요소, 예를 들어 물 오버 헤드가없는 모든 맛의 합으로 소스를 끓입니다. :-)
CB Du Rietz

97
var arr = [1,2,3,4];
var total=0;
for(var i in arr) { total += arr[i]; }

3
이것은 위의 jQuery.each () 솔루션보다 훨씬 빠릅니다.
Angry Dan

41
@Sprog : 그러나 사용 (var i=0; i<arr.length; i++)이 훨씬 빠릅니다. 그럼에도 불구하고 사용 var sum=0; var i=arr.length; while(i--) sum += arr[i]은 훨씬 더 빠릅니다.
Riking

14
for... in이 경우 _ coincidentally_ 배열에서 루프를 사용하면 배열이 객체를 확장하기 때문에 작동합니다. Riking의 솔루션이 더 좋습니다
Benjamin Gruenbaum

2
@BenjaminGruenbaum은 배열의 프로토 타입에 열거 할 수있는 속성을 추가 한 것이 없다고 제안했습니다.
canon

1
@YSC 아니오, 그렇지 않습니다. for...inJavaScript 의 루프는 인덱스를 가져옵니다.이 값은 값을 얻을 것으로 예상되는 코더의 일반적인 걸림돌입니다. ( for(var i in [1,2,3]) { console.log(i); }콘솔에서 시도하십시오 .)
Amber

61
var total = 0;
$.each(arr,function() {
    total += this;
});

87
reduce아래 의 답변을 사용하십시오 . 변수가없는 경우 가변 변수를 선언하지 마십시오.
Bruno Grieder


11
"허용 된 답변"이더라도 이것을 사용하지 마십시오. 아래 Florian의 답변이 훨씬 좋습니다!
Andy Sinclair

12
@BrunoGrieder "필요하지 않을 때 가변 변수를 선언하지 마십시오"는 명령형 언어 에 대한 극도의 편견 입니다. 상상력에 의한 코드 냄새가 거의 없습니다. 타일러의 대답에는 전혀 문제가 없으며 타일러와 플로리안의 유일한 차이점은 스타일입니다.
Rob

5
OP에서 : $ .each가 유용 할 것이라고 생각했지만 그것을 구현하는 방법을 잘 모르겠습니다. 이것이 최선은 아니지만 OP의 요청에 응답하십시오.


29

이것은 모든 항목을 반복하고 각 반복에서 항목을- sum변수 에 추가하여 가능합니다 .

var array = [1, 2, 3];

for (var i = 0, sum = 0; i < array.length; sum += array[i++]);

JavaScript는 블록 범위를 알지 못하므로 접근 sum할 수 있습니다.

console.log(sum); // => 6

위와 동일하지만 간단한 기능으로 주석을 달고 준비했습니다.

function sumArray(array) {
  for (
    var
      index = 0,              // The iterator
      length = array.length,  // Cache the array length
      sum = 0;                // The total amount
      index < length;         // The "for"-loop condition
      sum += array[index++]   // Add number on each iteration
  );
  return sum;
}

12
영리하지만 sum루프 외부에서 훨씬 더 읽기 쉬운 코드를 발견했습니다 .
Beni Cherniavsky-Paskin

@ BeniCherniavsky-Paskin 그래, 여기도 똑같아 ... 내가 왜 그런 식으로 그 일을했는지 ​​모르겠다 ... 그러나 나는 그것을 그대로 내버려 둘 것이다! 그것은 우리가 어떻게 할 수 있는지에 대한 예일뿐입니다 ... ;)
yckart

ES6부터 javascript DOES는 constand로 블록 범위를 알고 let있습니다. 따라서 루프 sum외부 를로 선언 할 수 있습니다 . 루프 전에 배열 길이를 다음과 같이 캐시 할 수도 있습니다.forlet sum = 0;const length = array.length;
KSK

23
arr.reduce(function (a, b) {
    return a + b;
});

참조 : Array.prototype.reduce ()


6
경우에 실패합니다 arr입니다 [].

7
다음과 같이 기본값을 추가하십시오.arr.reduce(function (a, b) { return a + b; }, 0);
Ngz

15
// Given array 'arr'
var i = arr.length;
var sum = 0;
while (--i) sum += arr[i];

eval()위 의 방법으로 3.604ms / run 및 (i, length, ++ 표준 으로 2.151ms / run과 비교할 때 평균 1.57ms / run (100 개의 임의의 일반 숫자 배열에서 1000 회 이상 측정)이 소요됩니다. ) 루프.

방법론 참고 :이 테스트는 Google Apps Script 서버에서 실행되었으므로 자바 스크립트 엔진은 Chrome과 거의 동일합니다.

편집 : --i대신i-- 매 실행마다 0.12ms 절약하는 (i--는 1.7)

편집 : 거룩한 expletive이 게시물 전체를 신경 쓰지 마십시오. 위에서 언급 한 reduce () 메소드를 사용하십시오. 단 1ms / run입니다.


1
나는 당신이 사용한 타이밍을 좋아합니다. 당신의 대답은 단지 "Pick me, I 'm best!"라고 말하는 것이 아닙니다. 대신 우리에게 보여줍니다 . 어쨌든, while (--i) do_something다른 일에도 효과 가 있을 수 있습니다.
Redwolf 프로그램

var sum = arr[0]
noobninja


12

나와 같은 기능적인 oneliner를 찾는 사람이 있습니까? 이것을 가지고 :

sum= arr.reduce(function (a, b) {return a + b;}, 0);

2 번째 매개 변수로 축소를위한 초기 값을 추가 할 수 있습니다.arr.reduce(function(a, b) { return a + b;}, 0);
Ngz

감사! 나는 그것을 통합합니다.
geek-merlin

12

재미있는 접근법 :

eval([1,2,3].join("+"))

5
이 코드에서 일어나는 일을 설명 하여이 답변을 확장 할 수 있습니까? 왜 작동합니까? 정확히 무엇을합니까? 이것들은 답변의 질을 향상시키는 데 도움이됩니다.
Ortund

@ user40521은 이미 내가 생각하는 방식으로 대답했습니다. 나는 그것을 보지 못했다.
전자

이것은 짧고 달콤하고 확실히 흥미롭지 만 매우 비효율적입니다. reduce전부는 아니지만 대부분의 경우에 사용하는 것이 확실히 바람직합니다.
Ninjakannon

Errm,[1,"2;YourProgram.ripToShreds();3",4]
Redwolf 프로그램

그래서 나는 잘못된 답변을 NaN시도 할 때 eval(['alert("removing your computer")',2,3].join("+"))0/10
pie6k

12

자, 아래 배열이 있다고 상상해보십시오.

const arr = [1, 2, 3, 4];

여기서 포괄적 인 답변을 찾을 수 없으므로 여러 가지 방법 으로 살펴 보기로하겠습니다.

1) 내장 reduce () 사용

function total(arr) {
  if(!Array.isArray(arr)) return;
  return arr.reduce((a, v)=>a + v);
}

2) for 루프 사용

function total(arr) {
  if(!Array.isArray(arr)) return;
  let totalNumber = 0;
  for (let i=0,l=arr.length; i<l; i++) {
     totalNumber+=arr[i];
  }
  return totalNumber;
}

3) while 루프 사용

function total(arr) {
  if(!Array.isArray(arr)) return;
  let totalNumber = 0, i=-1;
  while (++i < arr.length) {
     totalNumber+=arr[i];
  }
  return totalNumber;
}

4) 각 배열을 사용하여

function total(arr) {
  if(!Array.isArray(arr)) return;
  let sum=0;
  arr.forEach(each => {
    sum+=each;
  });
  return sum;
};

다음과 같이 호출하십시오.

total(arr); //return 10

이와 같은 것을 프로토 타입으로 배열하는 것은 권장하지 않습니다 ...


10

표준 JavaScript 솔루션 :

var addition = [];
addition.push(2);
addition.push(3);

var total = 0;
for (var i = 0; i < addition.length; i++)
{
    total += addition[i];
}
alert(total);          // Just to output an example
/* console.log(total); // Just to output an example with Firebug */

이것은 나를 위해 작동합니다 (결과는 5이어야합니다). 이런 종류의 솔루션에는 숨겨진 단점이 없기를 바랍니다.


1
또한 모든 C 또는 Java 프로그래머가이를 이해할 수 있습니다.
Audrius Meskauskas

모든 값을 요약하는 단순한 목적을 위해 단순한 평범한 오래된 for 루프는 실행 시간 측면에서 경쟁자가 없습니다
fedeghe

유일한 문제는, 20 개의 for 루프가 서로 중첩되어있을 때 약간 성가신 것입니다.
Redwolf Programs

7
var totally = eval(arr.join('+'))

그렇게하면 모든 종류의 이국적인 것들을 배열에 넣을 수 있습니다.

var arr = ['(1/3)','Date.now()','foo','bar()',1,2,3,4]

나는 반 농담입니다.


26
나는 반쯤 웃었다
caub

eval(['alert("removing your computer")',2,3].join("+"))
pie6k

7

나는 일반적으로 JavaScript와 코딩을 가진 초보자이지만 배열의 숫자를 합산하는 간단하고 쉬운 방법은 다음과 같습니다.

    var myNumbers = [1,2,3,4,5]
    var total = 0;
    for(var i = 0; i < myNumbers.length; i++){
        total += myNumbers[i];
    }

기본적으로 내장 함수를 사용하지 않는 많은 솔루션을 보지 못했기 때문에이 기여를 원했습니다.이 방법은 작성하고 이해하기 쉽습니다.


1
어떻게 이런 일이에서 어떤 다른 이 2012 대답 또는 이 2,014 대답은 ? 보지 못한 두 가지 솔루션이 있습니다.
Dan Dascalescu

5

JavaScript 코드의 짧은 조각이이 작업을 수행합니다.

var numbers = [1,2,3,4];
var totalAmount = 0;

for (var x = 0; x < numbers.length; x++) {

    totalAmount += numbers[x];
}

console.log(totalAmount); //10 (1+2+3+4)

5

몇몇 사람들은에 .sum()메소드를 추가 할 것을 제안 했습니다 Array.prototype. 이것은 일반적으로 나쁜 습관으로 간주되므로 그렇게 할 것을 제안하지는 않습니다.

여전히 그렇게 주장한다면, 이것은 간결하게 작성하는 방법입니다.

Array.prototype.sum = function() {return [].reduce.call(this, (a,i) => a+i, 0);}

그때: [1,2].sum(); // 3

프로토 타입에 추가 된 기능은 ES5 및 ES6 기능과 화살표 구문을 혼합하여 사용합니다. 은 function방법이 얻을 수 있도록 선언 this로부터 컨텍스트 Array당신이 작동하고 있는지를. 나는 전화 =>안에서 간결함을 위해 사용했다 reduce.


5

for루프를 사용하십시오 :

const array = [1, 2, 3, 4];
let result = 0;

for (let i = 0; i < array.length - 1; i++) {
  result += array[i];
}

console.log(result); // Should give 10

또는 forEach루프 :

const array = [1, 2, 3, 4];
let result = 0;

array.forEach(number => {
  result += number;
})

console.log(result); // Should give 10

간단하게하려면 reduce다음을 사용하십시오 .

const array = [10, 20, 30, 40];
const add = (a, b) => a + b
const result = array.reduce(add);

console.log(result); // Should give 100

4

필요가 없습니다 initial value! no initial value가 전달되면 callback function목록의 첫 번째 요소 에서 가 호출되지 않고 첫 번째 요소가 대신로 전달되기 때문 initial value입니다. 매우 c OO l 기능 :)

[1, 2, 3, 4].reduce((a, x) => a + x) // 10
[1, 2, 3, 4].reduce((a, x) => a * x) // 24
[1, 2, 3, 4].reduce((a, x) => Math.max(a, x)) // 4
[1, 2, 3, 4].reduce((a, x) => Math.min(a, x)) // 1

4

다음은 스택 알고리즘 을 사용하는 우아한 단일 라이너 솔루션입니다 .이 구현의 아름다움을 이해하는 데 시간이 걸릴 수 있습니다.

const getSum = arr => (arr.length === 1) ? arr[0] : arr.pop() + getSum(arr);

getSum([1, 2, 3, 4, 5]) //15

기본적으로 함수는 배열을 허용하고 배열에 정확히 하나의 항목이 포함되어 있는지 확인합니다. false 인 경우 스택에서 마지막 항목을 팝하고 업데이트 된 배열을 반환합니다.

이 스 니펫의 장점은 함수에 arr[0]무한 반복을 방지하기위한 검사가 포함되어 있다는 것 입니다. 마지막 항목에 도달하면 전체 합계를 반환합니다.


4

reduce () 메서드를 람다 식과 결합 할 수 있습니다.

[1, 2, 3, 4].reduce((accumulator, currentValue) => accumulator + currentValue);


3

나는 모든 대답이 '감소'솔루션으로가는 것을 보았습니다.

var array = [1,2,3,4]
var total = 0
for (var i = 0; i < array.length; i++) {
    total += array[i]
}
console.log(total)

3

정확성

배열을 정렬하고 가장 작은 숫자의 시작 합계 (스 니펫은 비 정렬과의 차이를 보여줍니다)

[...arr].sort((a,b)=>a-b).reduce((a,c)=>a+c,0)

다차원 숫자 배열의 경우 arr.flat(Infinity)


2

멋진 트릭은 배열의 길이를 캐싱하지 않는 안전한 전통적 답변이 많은 니트 선택입니다.

function arraySum(array){
  var total = 0,
      len = array.length;

  for (var i = 0; i < len; i++){
    total += array[i];
  }

  return total;
};

var my_array = [1,2,3,4];

// Returns 10
console.log( arraySum( my_array ) );

배열의 길이를 캐싱하지 않고 JS 컴파일러는 루프를 반복 할 때마다 배열을 통해 길이를 계산해야하므로 대부분의 경우 불필요한 오버 헤드가 발생합니다. V8과 많은 최신 브라우저가이를 최적화 해 주었기 때문에 그다지 신경 쓰지 않아도되지만이 간단한 캐싱의 혜택을받는 구형 장치가 있습니다.

길이가 변경 될 수있는 경우, 길이를 캐싱하는 이유를 모르는 경우 캐싱으로 인해 예기치 않은 부작용이 발생할 수 있지만 재사용 가능한 함수의 경우 유일한 목적은 배열을 가져 와서 값을 추가하는 것입니다. 잘 맞습니다.

이 arraySum 함수에 대한 CodePen 링크는 다음과 같습니다. http://codepen.io/brandonbrule/pen/ZGEJyV

이것이 나에게 붙어있는 오래된 사고 방식 일 가능성이 있지만,이 맥락에서 그것을 사용하는 데 불리한 점은 없습니다.


길이 캐싱 문제는 빨간 청어입니다. JS 엔진은 깜박이지 않고이를 최적화합니다.

2

그것들은 정말로 훌륭한 대답이지만 질문 (1,2,3,4)과 같이 숫자가 순서대로있는 경우 공식 (n * (n + 1)) / 2를 적용하여 쉽게 수행 할 수 있습니다. n은 마지막 숫자입니다


2
Object.defineProperty(Object.prototype, 'sum', {
    enumerable:false,
    value:function() {
        var t=0;for(var i in this)
            if (!isNaN(this[i]))
                t+=this[i];
        return t;
    }
});

[20,25,27.1].sum()                 // 72.1
[10,"forty-two",23].sum()          // 33
[Math.PI,0,-1,1].sum()             // 3.141592653589793
[Math.PI,Math.E,-1000000000].sum() // -999999994.1401255

o = {a:1,b:31,c:"roffelz",someOtherProperty:21.52}
console.log(o.sum());              // 53.519999999999996

이 코드는 운영 체제를 제거합니까? 아니면 나에게 당신의 개인 정보를 보내나요?

2

이것은 훨씬 쉽다

function sumArray(arr) {
    var total = 0;
    arr.forEach(function(element){
        total += element;
    })
    return total;
}

var sum = sumArray([1,2,3,4])

console.log(sum)

2

간단한 방법 예 :

function add(array){
    var arraylength = array.length;
    var sum = 0;
    for(var timesToMultiply = 0; timesToMultiply<arraylength; timesToMultiply++){
        sum += array[timesToMultiply];
    }

    return sum;
}

console.log(add([1, 2, 3, 4]));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.