2017-07-25 45 views
3

我與一個超級簡單的數據集reduce功能的工作,和我越來越NaN作爲結果的時候我沒有料到,簡單Reduce函數 - JavaScript的

let students = [{name: 'Leah', grade: 94},{name: 'Savannah', grade: 73},{name: 'Killian', grade: 38}]; 

let highest = students.reduce(
    (high, current) => Math.max(high.grade, current.grade) 
    ) 

console.log(highest); // outputs NaN 

怪異的事情是,如果我改變的第一行到以下內容:(剛取出第三個目的)

let students = [{name: 'Leah', grade: 94},{name: 'Savannah', grade: 73}]; 

然後這個正確運行和輸出94


爲什麼添加一個額外的對象會導致問題?

+4

通過與調試代碼步驟。每次循環時,檢查「high」和「current」的值。你應該能夠很快找出問題。 – 2017-07-25 04:40:46

回答

7

這一切都與什麼是在累加器(high)做。如果您沒有提供reduce的第二個參數,則累加器將作爲第一個對象開始,而當前元素是第二個元素。在第一次迭代中,您將累加器視爲對象,使用high.grade獲取分數;但是然後你返回一個數字(94),而不是一個對象,成爲你的下一個累加器。在循環的下一次迭代中,high不再是一個對象,而是94(94).grade是沒有意義的。

當您刪除第三個元素時,沒有第二次迭代,並且沒有時間發生錯誤,並且獲得當前累加器的值(94)。如果只有一個元素,你會得到初始累加器({name: 'Leah', grade: 94})。很明顯,這並不理想,因爲您無法可靠地預測計算結果的形狀(對象,數字或錯誤)。

您需要決定是否要數或對象,一方或另一方。

let highest = students.reduce(
    (high, current) => Math.max(high, current.grade), 
    Number.NEGATIVE_INFINITY 
) 

這種變體保持所述蓄能器爲數字,並且將返回94。我們不能依賴默認的起始累加器,因爲它需要是一個數字,所以我們在-INF處人爲設置它。

let highest = students.reduce(
    (high, current) => high.grade > current.grade ? high : current, 
) 

這是對象的版本,其中與highest{name: 'Leah', grade: 94}結束。

+0

謝謝,應該已經看到了。我正確地說,這個[mozilla頁面](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce)上的例子實際上會失敗,如果只有一個對象被添加? (在Description標題下的第一個示例) – qarthandso

+0

是的,如果添加另一個對象,它將返回NaN。您可以在控制檯中輕鬆進行測試以進行驗證。 –

+0

@qarthandso對於描述中的第一個例子,他們說你應該使用'。map'和一個初始值,而不是'reduce()without initialValue'的例子。但他們也應該將失敗案例列入三個對象。 –

2

這裏的問題是第一遍後累加器(高)是一個數字(什麼得到由math.max返回),但每一趟都需要高與品位多項屬性的對象。所以通過第二個電話,你打電話Math.max(undefined, 73) - 這將返回NaN。相反,我建議你用-Infinity,只提供high初始化累加器:

let highest = students.reduce( (high, current) => Math.max(high, current.grade) , -Infinity)