예를 들어 처음 n개의 자연수를 포함하는 숫자 배열이 주어졌지만 하나의 요소가 배열에 두 번 나타나므로 요소의 총 수는 n+1입니다. 우리의 임무는 배열을 받아 선형 시간에 두 번 나타나는 숫자를 반환하는 함수를 작성하는 것입니다.
방법 1:Array.prototype.reduce() 사용
이것은 조금 더 까다롭지만 작성된 코드 측면에서 가장 압축적입니다. 먼저 코드를 살펴보겠습니다 -
const arr = [1,4,8,5,6,7,9,2,3,7]; const duplicate = a => a.reduce((acc, val, ind) => val+acc- (ind+1))+a.length-1; console.log(duplicate(arr));
여기에서 우리는 배열의 각 요소에 대해 한 번씩 작동하는 리듀스 함수의 콜백을 사용했습니다. 이 경우에는 세 개의 인수를 사용합니다.
- acc → 누산기, 이전 패스에서 반환된 값 및
- val → 현재 요소 값,
- ind → 현재 요소의 인덱스
이제 이 배열에 코드를 적용해 보겠습니다 -
[ 2, 3, 1, 2]
이 배열의 길이가 4이므로 총 4번의 콜백 함수 전달이 있어야 하지만, reduce() 함수에 initialValue 인수를 제공하지 않았기 때문에 반복은 인덱스 1에서 시작하고 누산기는 처음에 다음 값으로 할당됩니다. 0번째 인덱스이므로 총 3개의 패스가 있습니다.
첫 번째 패스
acc = 2, val = 3, ind = 1 return value = 2+3 - (1+1) = 3
두 번째 패스
acc = 3, val = 1, ind = 2 return value = 3+1 - (2+1) = 1
세 번째 패스
acc = 1, val = 2, ind = 3 return value = 1+2 - (3+1) = -1
어레이 끝
따라서 배열에서 -1이 반환된 다음
-1 + (4-1) = -1 + 3 = 2
실제로 올바른 결과인 duplicate() 함수에서 반환됩니다.
방법 2:Array.prototype.forEach()
이 방법에서 우리는 배열을 반복하고, 그 합을 구하고, 그것에서 첫 번째(n-1) 자연수의 합을 뺍니다. 여기서 n은 배열의 길이이고, 남은 것은 두 번 반복된 숫자이므로 반환합니다. 입니다.
예시
const arr = [1,4,8,5,6,7,9,2,3,7]; const duplicate = a => { let sum = 0; const { length: n } = a; a.forEach(num => sum += num); return sum - ((n*(n-1))/2); } console.log(duplicate(arr));
출력
콘솔의 출력은 다음과 같습니다. -
7