假設我有以下陣列:
let arr = [{a: 1, b: 2}, {a: 2, b: 4}, {a: 8, b: -1}]
我想計算每個鍵的累積總和,但我也希望輸出是一個長度相同的陣列,每個步驟都有累積值。最終結果應該是:
[{a: 1, b: 2}, {a: 3, b: 6}, {a: 11, b: 5}]
我的問題是我無法根據需要獲取陣列。我只得到最終的物件:
let result = arr.reduce((accumulator, element) => {
if(accumulator.length === 0) {
accumulator = element
} else {
for(let i in element){
accumulator[i] = accumulator[i] element[i]
}
}
return accumulator
}, [])
console.log(result); // {a: 11, b: 5}
uj5u.com熱心網友回復:
您所追求的聽起來像是scan()高階函式(借用ramda.js的想法),它允許您回傳陣列中每個元素的累積結果。scan 方法類似于該.reduce()方法的行為方式,不同之處在于它回傳每個元素的累加器。您可以scan()像這樣自己構建函式:
let arr = [{a: 1, b: 2}, {a: 2, b: 4}, {a: 8, b: -1}];
const scan = ([x, ...xs], fn) => xs.reduce((acc, elem) => {
return [...acc, fn(acc.at(-1), elem)];
}, xs.length ? [x] : []);
const res = scan(arr, (x, y) => ({a: x.a y.a, b: x.b y.b}));
console.log(res);
您可能會考慮進一步改進,例如為 scan 方法提供初始值(類似于 reduce 接受一個值的方式)。此外,如果您需要更好的瀏覽器支持,該.at()方法目前的瀏覽器支持有限,因此您可以考慮創建自己的at()函式:
const at = (arr, idx) => idx >= 0 ? arr[idx] : arr[arr.length idx];
uj5u.com熱心網友回復:
您可以使用reduceas輕松實作結果
let arr = [
{ a: 1, b: 2 },
{ a: 2, b: 4 },
{ a: 8, b: -1 },
];
const result = arr.reduce((acc, curr, i) => {
if (i === 0) acc.push(curr);
else {
const last = acc[i - 1];
const newObj = {};
Object.keys(curr).forEach((k) => (newObj[k] = curr[k] last[k]));
acc.push(newObj);
}
return acc;
}, []);
console.log(result);
uj5u.com熱心網友回復:
像這樣的東西:
const arr = [{a: 1, b: 2}, {a: 2, b: 4}, {a: 8, b: -1}]
const result = arr.reduce((accumulator, element, index) => {
if(accumulator.length === 0) {
accumulator.push(element)
} else {
const sum = {};
for(let i in element) {
sum[i] = element[i] (accumulator[index - 1][i] || 0)
}
accumulator.push(sum)
}
return accumulator
}, [])
console.log(result);
另一種選擇是使用 a 保持總和結果Map,如果陣列元素中的鍵不總是相同,它會有所幫助。
const arr = [{a: 1, b: 2}, {a: 2}, {a: 8, b: -1}];
const map = new Map();
const result = arr.map((element) => {
const sum = {};
for (let i in element) {
sum[i]= element[i] (map.get(i) || 0);
map.set(i, sum[i]);
}
return sum;
});
console.log(result);
uj5u.com熱心網友回復:
這是一個更簡潔的reduce,結果可能不那么可讀......
array.reduce((y,x,i) => ( i===0 ? y : [...y, {a: x.a y[i-1].a, b: x.b y[i-1].b}]),[array[0]])
let array = [{a: 1, b: 2}, {a: 2, b: 4}, {a: 8, b: -1}]
let culm = array.reduce((y,x,i) => ( i===0 ? y : [...y, {a: x.a y[i-1].a, b: x.b y[i-1].b}]),[array[0]])
console.log(culm)
uj5u.com熱心網友回復:
鑒于:
const xs =
[ {a: 1, b: 2}
, {a: 2, b: 4}
, {a: 8, b: -1}];
定義一個函式,sum例如:
const sum = ([head, ...tail]) =>
tail.reduce((x, y) =>
({a: (x.a y.a), b: (x.b y.b)}), head);
sum(xs);
//=> {a: 11, b: 5}
然后在更大切片的地圖中應用該函式xs:
xs.map((_, i, arr) => sum(arr.slice(0, i 1)));
//=> [ {a: 1, b: 2}
//=> , {a: 3, b: 6}
//=> , {a: 11, b: 5}]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/376515.html
標籤:javascript 目的 函数式编程
