속성 합계를 위해 객체 배열에 대한 감소를 호출하려면 어떻게 해야 합니까?
I sum Summary Say I want to summarya.x
의 각 arr
.
arr = [ { x: 1 }, { x: 2 }, { x: 4 } ];
arr.reduce(function(a, b){ return a.x + b.x; }); // => NaN
라고 a.x
undefined
어느 순간엔가.
이하대로 동작합니다.
arr = [ 1, 2, 4 ];
arr.reduce(function(a, b){ return a + b; }); // => 7
첫 번째 예에서 제가 무엇을 잘못하고 있을까요?
하기 위해서는 두 .reduce
:
var arr = [{x:1}, {x:2}, {x:4}];
var result = arr.reduce(function (acc, obj) { return acc + obj.x; }, 0);
console.log(result); // 7
때, 「」로 됩니다.(0, {x: 1})
를 반환한다.0 + 1 = 1
음음음, 는전 . with with로 (1, {x: 2})
를 반환한다.1 + 2 = 3
해서 '라고 해요(3, {x: 4})
으로 반환(반환)7
.
, 비어 있는 에서도, 「어레이는 비어 있습니다」, 「어레이는 비어 있습니다」, 「어레이는 비어 있습니다」를 반환합니다.0
.
x
에 undefined
관련된 수학입니다.undefined
이 되다NaN
을 x
"X" "X" "X"
var arr = [{x:1},{x:2},{x:4}];
arr.reduce(function (a, b) {
return {x: a.x + b.x}; // returns object with property x
})
// ES6
arr.reduce((a, b) => ({x: a.x + b.x}));
// -> {x: 7}
코멘트에서 추가된 설명:
의 각 [].reduce
로 the the the a
변수를 지정합니다.
1: 1 1:a = {x:1}
,,b = {x:2}
,,{x: 3}
할당된 에에 할당된다.a
Iteration 2반복 2에서에
Iteration 2:반복 2:a = {x:3}
,,b = {x:4}
..
이 예제의 문제는 숫자 리터럴을 반환한다는 것입니다.
function (a, b) {
return a.x + b.x; // returns number literal
}
Iteration 1:반복 1:a = {x:1}
,,b = {x:2}
,,// returns 3
~하듯이로a
다음 iteration다음 반복에서는에
Iteration 2:반복 2:a = 3
,,b = {x:2}
수익 돌아온다NaN
많은 문자 그대로의 숫자 리터럴3
에는 ( (이 없습니다.x
그그 so soundefined
★★★★★★★★★★★★★★★★★」undefined + b.x
NaN
★★★★★★★★★★★★★★★★★」NaN + <anything>
있다NaN
설명:숫자 프리미티브를 꺼내기 위해 매직 넘버로 줄이는 선택적 파라미터를 전달하는 것이 더 깔끔하다는 생각에 동의하지 않기 때문에 이 스레드의 다른 상위 답변보다 내 방법을 선호합니다.적은 행이 쓰여질 수 있지만 읽기 어렵습니다.
TL;DR, 초기값 설정
파괴 사용
arr.reduce( ( sum, { x } ) => sum + x , 0)
파괴하지 않고
arr.reduce( ( sum , cur ) => sum + cur.x , 0)
타이프 스크립트 포함
arr.reduce( ( sum, { x } : { x: number } ) => sum + x , 0)
파괴 방법을 시험해 보겠습니다.
const arr = [ { x: 1 }, { x: 2 }, { x: 4 } ]
const result = arr.reduce( ( sum, { x } ) => sum + x , 0)
console.log( result ) // 7
그 열쇠는 초기값을 설정하는 것입니다.반환값은 다음 반복의 첫 번째 파라미터가 됩니다.
상위 답변에 사용된 기법이 관용적이지 않습니다.
승인된 답변은 "옵션" 값을 전달하지 않을 것을 제안합니다.두 번째 파라미터는 항상 포함되기 때문에 이는 잘못된 것입니다.왜? 세 가지 이유:
1. 위험 - 초기값을 전달하지 않으면 위험하며 콜백 함수가 부주의할 경우 부작용이나 돌연변이가 발생할 수 있습니다.
등록하세요.
const badCallback = (a,i) => Object.assign(a,i)
const foo = [ { a: 1 }, { b: 2 }, { c: 3 } ]
const bar = foo.reduce( badCallback ) // bad use of Object.assign
// Look, we've tampered with the original array
foo // [ { a: 1, b: 2, c: 3 }, { b: 2 }, { c: 3 } ]
이 방법으로 초기값을 설정했다면 다음과 같습니다.
const bar = foo.reduce( badCallback, {})
// foo is still OK
foo // { a: 1, b: 2, c: 3 }
오브젝트를 첫 는 "Matrix"로 합니다.Object.assign
을 사용하다하다, 하다, 하다, 하다.Object.assign({}, a, b, c)
.
2 - 더 나은 유형 추론 - Typescript와 같은 툴이나 VS Code와 같은 에디터를 사용할 경우 컴파일러에 이니셜을 알려주는 이점을 얻을 수 있으며, 잘못하면 오류를 발견할 수 있습니다.초기값을 설정하지 않으면 대부분의 경우 추측이 불가능하여 실행 시 오류가 발생할 수 있습니다.
3 - 펑터 존중 - JavaScript는 내부의 기능적 자식이 해방되었을 때 가장 빛납니다.기능적인 세계에서는, 「접기」또는 「접기」에 관한 기준이 있습니다.reduce
배열이형성을 접거나 배열에 적용할 때 해당 배열 값을 사용하여 새 유형을 구성합니다.최종 유형이 어레이, 다른 어레이 또는 다른 유형의 값인 경우에도 결과 유형을 전달해야 합니다.
다른 방법으로 생각해 봅시다.JavaScript에서는 데이터처럼 함수를 전달할 수 있습니다.콜백은 이렇게 동작합니다.다음 코드의 결과는 무엇입니까?
[1,2,3].reduce(callback)
번호가 반환됩니까?물건이요?이렇게 하면 더 선명해집니다.
[1,2,3].reduce(callback,0)
기능 프로그래밍 사양에 대한 자세한 내용은 https://github.com/fantasyland/fantasy-land#foldable를 참조하십시오.
다른 배경
reduce
는 2개의 즉 2개의 가 있습니다.
Array.prototype.reduce( callback, initialItem )
callback
는 다음 변수를 합니다.
(accumulator, itemInArray, indexInArray, entireArray) => { /* do stuff */ }
첫 번째 반복에서는
if
initialItem
제공되고 있습니다.reduce
가 을initialItem
처accumulator
의 첫 은 ""로 됩니다.itemInArray
.if
initialItem
는 제공되지 않습니다.reduce
의 첫 을 ""로 합니다.initialItem
의 두 은 " " " 입니다.itemInArray
혼란스러운 행동일 수 있습니다.
저는 항상 초기값인 reduced를 설정하는 것을 가르치고 권장하고 있습니다.
다음 사이트에서 문서를 확인할 수 있습니다.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
이게 도움이 됐으면 좋겠네요!
다른 사람들은 이 질문에 답했지만, 나는 다른 방법을 택하려고 했다.a.x를 직접 합산하는 대신 (a.x에서x로) 맵을 조합하여 (x를 추가하기 위해) 축소할 수 있습니다.
arr = [{x:1},{x:2},{x:4}]
arr.map(function(a) {return a.x;})
.reduce(function(a,b) {return a + b;});
물론, 조금 더 느리겠지만, 옵션으로 언급할 가치가 있다고 생각했습니다.
지적된 내용을 공식화하기 위해, 리덕터는 우연에 의해 같은 타입일 수 있는2개의 인수를 취하여 첫 번째 인수에 일치하는 유형을 반환하는 카타몰피즘입니다.
function reducer (accumulator: X, currentValue: Y): X { }
, 는 ,, 원, currentValue
값 및 " " " 입니다.accumulator
의 accumulator
.
이는 적산기와 요소 값이 모두 같은 유형이지만 다른 용도로 사용되기 때문에 덧셈할 때 간단한 방식으로 작동합니다.
[1, 2, 3].reduce((x, y) => x + y);
모두 숫자이기 때문에 효과가 있습니다.
[{ age: 5 }, { age: 2 }, { age: 8 }]
.reduce((total, thing) => total + thing.age, 0);
이제 애그리게이터에 시작값을 부여합니다.대부분의 경우 시작 값은 애그리게이터가 예상하는 유형(최종값으로 예상되는 유형)이어야 합니다.이것을 강요당하는 것은 아니지만(그렇게 해서는 안 된다) 명심하는 것이 중요합니다.
이 사실을 알게 되면 다른 n:1 관계 문제에 대해 의미 있는 축소를 작성할 수 있습니다.
반복되는 단어 삭제:
const skipIfAlreadyFound = (words, word) => words.includes(word)
? words
: words.concat(word);
const deduplicatedWords = aBunchOfWords.reduce(skipIfAlreadyFound, []);
발견된 모든 단어 수:
const incrementWordCount = (counts, word) => {
counts[word] = (counts[word] || 0) + 1;
return counts;
};
const wordCounts = words.reduce(incrementWordCount, { });
어레이를 단일 플랫 어레이로 축소:
const concat = (a, b) => a.concat(b);
const numbers = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
].reduce(concat, []);
여러 가지 요소에서 1:1과 일치하지 않는 단일 값으로 전환하려는 경우 언제든지 줄일 것을 고려할 수 있습니다.
실제로 맵과 필터는 둘 다 절감으로 구현할 수 있습니다.
const map = (transform, array) =>
array.reduce((list, el) => list.concat(transform(el)), []);
const filter = (predicate, array) => array.reduce(
(list, el) => predicate(el) ? list.concat(el) : list,
[]
);
문맥을 을 좀 더 알 수 있기를 .reduce
.
여기에 추가된 한 가지 사항은 아직 설명하지 않았지만 어레이 요소가 함수이기 때문에 입력 및 출력 유형이 특히 역동적일 것으로 예상되는 경우입니다.
const compose = (...fns) => x =>
fns.reduceRight((x, f) => f(x), x);
const hgfx = h(g(f(x)));
const hgf = compose(h, g, f);
const hgfy = hgf(y);
const hgfz = hgf(z);
첫 번째 반복에서는 'a'가 배열의 첫 번째 개체가 되므로 a.x + b.x는 1+2 즉, 3을 반환합니다.다음 반복에서는 반환된3이 a에 할당되기 때문에 a는 n개의 발신번호이며, a.x는 NaN을 제공합니다.
간단한 솔루션은 먼저 어레이 내의 숫자를 매핑한 후 다음과 같이 줄이는 것입니다.
arr.map(a=>a.x).reduce(function(a,b){return a+b})
(여기서)arr.map(a=>a.x)
는, 「1,2, 4」를 사용하고, 「1, 2, 4..reduce(function(a,b){return a+b})
에서는, 이러한 .이러한 번호는, 「」이라고는 할 수 없습니다.
또 다른 간단한 해결책은 다음과 같이 "a"에 0을 할당하여 초기 합계를 0으로 제공하는 것입니다.
arr.reduce(function(a,b){return a + b.x},0)
마다 새 .{x:???}
중 를 해야 을 사용하다
arr = [{x:1},{x:2},{x:4}]
arr.reduce(function(a,b){return a + b.x})
아니면 네가 해야 해
arr = [{x:1},{x:2},{x:4}]
arr.reduce(function(a,b){return {x: a.x + b.x}; })
객체 배열과 같이 데이터가 많은 복잡한 객체가 있는 경우 이를 해결하기 위해 단계별로 접근할 수 있습니다.
예:
const myArray = [{ id: 1, value: 10}, { id: 2, value: 20}];
먼저 어레이를 원하는 새 배열에 매핑해야 합니다. 이 예에서는 새로운 값 배열일 수 있습니다.
const values = myArray.map(obj => obj.value);
이 콜백 함수는 원래 배열의 값만 포함하는 새 배열을 반환하고 값 const에 저장합니다.값 const는 다음과 같은 배열입니다.
values = [10, 20];
이제 절감 작업을 수행할 준비가 되었습니다.
const sum = values.reduce((accumulator, currentValue) => { return accumulator + currentValue; } , 0);
보시다시피 reduce 메서드는 콜백 기능을 여러 번 실행합니다.각 시간마다 배열에 있는 항목의 현재 값을 가져와서 누적기와 합합니다.따라서 이 값을 적절히 합산하려면 축척 방법의 두 번째 인수로 축척기의 초기 값을 설정해야 합니다.
이제 값이 30인 새 고정합계가 나왔습니다.
ES6에서는 조금 개선했습니다.
arr.reduce((a, b) => ({x: a.x + b.x})).x
반송 번호
첫 번째 단계에서, 그것은 가치로서 잘 기능할 것이다.a
이 되고 1은 1이 되고 1은 1이 .b
2에서는 2+됩니다.b
.from step 1 i.e 3
★★★★★★★★★★★★★★★★★」b.x
되지 않은 + 이 되기 수 .「정의 없음 + anyNumber 」NaN이다.그 때문에, 그 결과가 표시됩니다.
대신 초기값을 0으로 지정하면 됩니다.
arr.reduce(function(a,b){return a + b.x},0);
지금까지의 개발은 다음과 같습니다.솔루션을 내 환경에서 재사용할 수 있는 기능으로 정리하는 것입니다.
const sumArrayOfObject =(array, prop)=>array.reduce((sum, n)=>{return sum + n[prop]}, 0)
오브젝트 리터럴로 디폴트값을 설정하는 데 2센트만 있으면 됩니다.
let arr = [{
duration: 1
}, {
duration: 3
}, {
duration: 5
}, {
duration: 6
}];
const out = arr.reduce((a, b) => {
return {
duration: a.duration + b.duration
};
}, {
duration: 0
});
console.log(out);
컬렉션에 대해 기능 반복을 줄이다
arr = [{x:1},{x:2},{x:4}] // is a collection
arr.reduce(function(a,b){return a.x + b.x})
번역자:
arr.reduce(
//for each index in the collection, this callback function is called
function (
a, //a = accumulator ,during each callback , value of accumulator is
passed inside the variable "a"
b, //currentValue , for ex currentValue is {x:1} in 1st callback
currentIndex,
array
) {
return a.x + b.x;
},
accumulator // this is returned at the end of arr.reduce call
//accumulator = returned value i.e return a.x + b.x in each callback.
);
각 인덱스 콜백 중에 변수 "a" 값이 콜백 함수의 "a" 파라미터로 전달됩니다."accumulator"를 초기화하지 않으면 값은 정의되지 않습니다.undefined.x를 호출하면 오류가 발생합니다.
이 문제를 해결하려면 위의 Casey 답변과 같이 값 0으로 "누적기"를 초기화하십시오.
reduce 함수의 in-out을 이해하기 위해서는 이 함수의 소스 코드를 보는 것이 좋습니다.Lodash 라이브러리는 ES6의 "reduce" 기능과 동일하게 기능하는 reduce 기능을 가지고 있습니다.
다음은 소스 코드 축소 링크입니다.
을 x
추가:
arr.reduce(
(a,b) => (a.x || a) + b.x
)
0(제로)을 1 또는 다른 수치로 변경하면 총수에 추가됩니다.예를 들어, 이 예에서는 총수를 31로 지정하고 있습니다만, 0을 1로 변경하면 총수는 32가 됩니다.
const batteryBatches = [4, 5, 3, 4, 4, 6, 5];
let totalBatteries= batteryBatches.reduce((acc,val) => acc + val ,0)
function aggregateObjectArrayByProperty(arr, propReader, aggregator, initialValue) {
const reducer = (a, c) => {
return aggregator(a, propReader(c));
};
return arr.reduce(reducer, initialValue);
}
const data = [{a: 'A', b: 2}, {a: 'A', b: 2}, {a: 'A', b: 3}];
let sum = aggregateObjectArrayByProperty(data, function(x) { return x.b; }, function(x, y) { return x + y; }, 0);
console.log(`Sum = ${sum}`);
console.log(`Average = ${sum / data.length}`);
let product = aggregateObjectArrayByProperty(data, function(x) { return x.b; }, function(x, y) { return x * y; }, 1);
console.log(`Product = ${product}`);
이전에 주어진 솔루션에서 일반적인 함수를 작성했습니다.저는 자바 개발자이기 때문에 실수나 자바스크립트 이외의 규격에 대해서는 사과드립니다:-)
let temp =[{x:1},
{x:2},
{x:3},
{x:4}];
let sum = temp.map(element => element.x).reduce((a, b) => a+ b , 0)
console.log(sum);
x의 합에 이 방법을 사용할 수 있다.
출력: 10
배열 축소 함수는 initialValue(기본값은 0), accumulator 및 current value의 세 가지 파라미터를 사용합니다.기본적으로 initialValue 값은 "0" 이며, 이는 accumulator에 의해 사용됩니다.
이것을 코드로 표시해 봅시다.
var arr =[1,2,4] ;
arr.reduce((acc,currVal) => acc + currVal ) ;
// (remember Initialvalue is 0 by default )
//first iteration** : 0 +1 => Now accumulator =1;
//second iteration** : 1 +2 => Now accumulator =3;
//third iteration** : 3 + 4 => Now accumulator = 7;
No more array properties now the loop breaks .
// solution = 7
다음으로 initial Value의 예를 나타냅니다.
var initialValue = 10;
var arr =[1,2,4] ;
arr.reduce((acc,currVal) => acc + currVal,initialValue ) ;
/
// (remember Initialvalue is 0 by default but now it's 10 )
//first iteration** : 10 +1 => Now accumulator =11;
//second iteration** : 11 +2 => Now accumulator =13;
//third iteration** : 13 + 4 => Now accumulator = 17;
No more array properties now the loop breaks .
//solution=17
오브젝트 어레이에도 동일하게 적용됩니다(현재 stackoverflow 질문).
var arr = [{x:1},{x:2},{x:4}]
arr.reduce(function(acc,currVal){return acc + currVal.x})
// destructing {x:1} = currVal;
Now currVal is object which have all the object properties .So now
currVal.x=>1
//first iteration** : 0 +1 => Now accumulator =1;
//second iteration** : 1 +2 => Now accumulator =3;
//third iteration** : 3 + 4 => Now accumulator = 7;
No more array properties now the loop breaks
//solution=7
한 가지 주의해야 할 점은 기본적으로 InitialValue는 0이며, {}, [] 및 숫자를 지정할 수 있습니다.
//fill creates array with n element
//reduce requires 2 parameter , 3rd parameter as a length
var fibonacci = (n) => Array(n).fill().reduce((a, b, c) => {
return a.concat(c < 2 ? c : a[c - 1] + a[c - 2])
}, [])
console.log(fibonacci(8))
축적기에 a.x를 사용하면 안 됩니다.대신 'arr = [{x:1}, {x:2}, {x:4}'와 같이 할 수 있습니다.
arr.disc(function(a, b){a + b.x},0)'
언급URL : https://stackoverflow.com/questions/5732043/how-to-call-reduce-on-an-array-of-objects-to-sum-their-properties
'programing' 카테고리의 다른 글
MySQL과 SQL Server의 차이점 (0) | 2022.10.11 |
---|---|
JavaScript에서 커스텀 오브젝트를 "적절하게" 작성하려면 어떻게 해야 합니까? (0) | 2022.10.11 |
Python 3 회전 범위를 목록으로 설정 (0) | 2022.10.11 |
C에서 C++를 우아하게 호출하다 (0) | 2022.10.11 |
java.displaces를 클릭합니다.예외:JUnit 실행에 실행 가능한 메서드 예외가 없습니다. (0) | 2022.10.11 |