我想減去結構完全相同的兩個物件的值。盡管這里存在一個答案,但僅限于沒有深度的物件。就我而言,我正在尋找一種強大的解決方案,只要它們具有相同的結構,就可以減去任何深度的物件。
例子
考慮以下兩個物件earthData2022和earthData2050:
const earthData2022 = {
distanceFromSun: 149280000,
continents: {
asia: {
area: 44579000,
population: 4560667108,
countries: { japan: { temperature: 62.5 } },
},
africa: { area: 30370000, population: 1275920972 },
europe: { area: 10180000, population: 746419440 },
america: { area: 42549000, population: 964920000 },
australia: { area: 7690000, population: 25925600 },
antarctica: { area: 14200000, population: 5000 },
},
};
const earthData2050 = {
distanceFromSun: 149280000,
continents: {
asia: {
area: 44579000,
population: 4560767108,
countries: { japan: { temperature: 73.6 } },
},
africa: { area: 30370000, population: 1275960972 },
europe: { area: 10180000, population: 746419540 },
america: { area: 42549000, population: 964910000 },
australia: { area: 7690000, population: 25928600 },
antarctica: { area: 14200000, population: 5013 },
},
};
請注意,這兩個物件都有:
- 完全相同的結構
- 所有值都是數字,整數或小數。沒有字串或布林值,也沒有陣列。
我想減去:earthData2050-earthData2022得到一個新物件:
// desired output
// continents' areas aren't expected to change so their diff is `0`
// likewise, the distance of earth from sun
const earthDataDiff = {
distanceFromSun: 0,
continents: {
asia: {
area: 0,
population: 100000,
countries: { japan: { temperature: 11.1 } },
},
africa: { area: 0, population: 40000 },
europe: { area: 0, population: 100 },
america: { area: 0, population: -10000 },
australia: { area: 0, population: 3000 },
antarctica: { area: 0, population: 13 },
},
};
如上所述,很容易使用這里給出的甜蜜答案:
function mySub(x, y) {
return Object.keys(x).reduce((a, k) => {
a[k] = x[k] - y[k];
return a;
}, {});
}
但是,在呼叫時,mySub()我們會得到這個不足為奇的輸出:
mySub(earthData2050, earthData2022)
// {"distanceFromSun":0,"continents":null}
因此,我的問題是,只要物件具有相同的結構,我如何遞回地減去所有條目,無論多深。此外,當我在 Node 上運行此代碼時,我很樂意使用任何可能派上用場的新 ECMAScript 功能。
uj5u.com熱心網友回復:
遞回是你的朋友
const earthData2022 = {
distanceFromSun: 149280000,
continents: {
asia: {
area: 44579000,
population: 4560667108,
countries: { japan: { temperature: 62.5 } },
},
africa: { area: 30370000, population: 1275920972 },
europe: { area: 10180000, population: 746419440 },
america: { area: 42549000, population: 964920000 },
australia: { area: 7690000, population: 25925600 },
antarctica: { area: 14200000, population: 5000 },
},
};
const earthData2050 = {
distanceFromSun: 149280000,
continents: {
asia: {
area: 44579000,
population: 4560767108,
countries: { japan: { temperature: 73.6 } },
},
africa: { area: 30370000, population: 1275960972 },
europe: { area: 10180000, population: 746419540 },
america: { area: 42549000, population: 964910000 },
australia: { area: 7690000, population: 25928600 },
antarctica: { area: 14200000, population: 5013 },
},
};
function mySub(x, y) {
const result = {}
Object.keys(x).forEach((key) => {
if (typeof x[key] === 'number') {
result[key] = x[key] - y[key]
} else {
result[key] = mySub(x[key], y[key])
}
});
return result;
}
console.log(mySub(earthData2050, earthData2022));
uj5u.com熱心網友回復:
宣告性/功能性解決方案:
const difference = (obj1, obj2) => Object.entries(obj1).reduce((t, [key, value]) => {
const obj2Value = obj2[key];
return {
...t,
[key]: typeof value === "object" ?
difference(value, obj2Value) :
value - obj2Value
};
}, {});
解釋
Object.entries將物件轉換為鍵值對的二維陣列。使用array.reduce迭代對,它可以將陣列減少為一個物件。與此類似的是,當您在烹飪時將肉湯減至醬汁時。如果屬性的值是一個物件,結果屬性應該是子物件的差值(遞回)。如果不是,它必須是一個數字,因此可以減去。
進一步閱讀:
- Array.prototype.reduce
- 遞回(函式呼叫自身)
- 物件條目
uj5u.com熱心網友回復:
這是一個非常簡單的遞回方法:
const objDiff = (x, y) => Object .fromEntries (
Object .entries (x) .map (([k, v]) => [
k,
Object (v) === v ? objDiff (v, y [k]) : v - y [k]
])
)
const earthData2022 = {distanceFromSun: 14928e4, continents: {asia: {area: 44579e3, population: 4560667108, countries: {japan: {temperature: 62.5}}}, africa: {area: 3037e4, population: 1275920972}, europe: {area: 1018e4, population: 746419440}, america: {area: 42549e3, population: 96492e4}, australia: {area: 769e4, population: 25925600}, antarctica: {area: 142e5, population: 5e3}}}
const earthData2050 = {distanceFromSun: 14928e4, continents: {asia: {area: 44579e3, population: 4560767108, countries: {japan: {temperature: 73.6}}}, africa: {area: 3037e4, population: 1275960972}, europe: {area: 1018e4, population: 746419540}, america: {area: 42549e3, population: 96491e4}, australia: {area: 769e4, population: 25928600}, antarctica: {area: 142e5, population: 5013}}}
console .log (objDiff (earthData2050, earthData2022))
.as-console-wrapper {max-height: 100% !important; top: 0}
我們獲取您的第一個物件中的條目并將它們映射到具有相同鍵和值的新條目,該值是遞回呼叫或減法的結果,具體取決于第一個值是物件還是數字。然后我們用它Object .fromEntries來重建一個新物件。
這僅在您的注釋正確、兩個物件具有相同的結構并且葉節點都是數字的情況下才有效。如果我們想處理其他情況,我們必須變得更加復雜。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/460992.html
標籤:javascript 递归 对象字面量
上一篇:打字稿嵌套物件結構條件/遞回型別
下一篇:遞回列印樹的節點時出錯
