2017-05-03 33 views
1

我正在使用reduce函數,它循環遍歷我的JSON文件並將指定的鍵值彙總在一起。使用reduce來循環JSON

這工作正常,直到我刪除其中的一個值。

我的JSON是:

[{ 
     "id": 100, 
     "jobNumber": 1, 
     "jobTasks": [{ 
       "id": 12, 
       "cost": { 
        "amountString": 100 
       } 
      }, 
      { 
       "id": 13, 
       "cost": { 
        "amountString": 500 
       } 
      } 
     ] 
    }, 
    { 
     "id": 101, 
     "jobNumber": 2, 
     "jobTasks": [{ 
       "id": 14, 
       "cost": { 
        "amountString": 100 
       } 
      }, 
      { 
       "id": 15 
      } 
     ] 
    } 
] 

的減少功能我用的是:

json.data.forEach(function(item) { 
var sum = item.jobTasks.reduce(function(sum, elem) { 
    return sum + elem.cost.amountString; 
}, 0); 
console.log('jobNumber' + item.jobNumber + ' ' + sum); 
}); 

我試圖做到這一點:

jobNumber1 600 
jobNumber2 100 

這將正常工作如果我在第二份工作中放置另一個cost.amountString,但是有兩個i n個第一和一個第二,如圖我的JSON上面,我得到以下錯誤:

TypeError: Cannot read property 'amountString' of undefined 

是否減少需要一個以上的或值對相同數量的工作?我嘗試過各種循環而沒有成功。

回答

2

您需要檢查第二個對象的undefined值,該對象沒有屬性amountString。如果對象中不存在屬性amountString,則返回值0

所以從
return sum + elem.cost.amountString;
改變return聲明要
return sum + (elem.cost && elem.cost.amountString ? elem.cost.amountString : 0) ;

完整代碼:

var json = {}; 
 
json.data = [{ 
 
     "id": 100, 
 
     "jobNumber": 1, 
 
     "jobTasks": [{ 
 
       "id": 12, 
 
       "cost": { 
 
        "amountString": 100 
 
       } 
 
      }, 
 
      { 
 
       "id": 13, 
 
       "cost": { 
 
        "amountString": 500 
 
       } 
 
      } 
 
     ] 
 
    }, 
 
    { 
 
     "id": 101, 
 
     "jobNumber": 2, 
 
     "jobTasks": [{ 
 
       "id": 14, 
 
       "cost": { 
 
        "amountString": 100 
 
       } 
 
      }, 
 
      { 
 
       "id": 15 
 
      } 
 
     ] 
 
    } 
 
] 
 

 

 
json.data.forEach(function(item) { 
 
var sum = item.jobTasks.reduce(function(sum, elem) { 
 
    return sum + (elem.cost && elem.cost.amountString ? elem.cost.amountString : 0) ; 
 
}, 0); 
 
console.log('jobNumber' + item.jobNumber + ' ' + sum); 
 
});

+1

謝謝!這真的有幫助!我是個笨蛋,不想用'?'早。 –

+0

很高興,它幫助:) – Agalo

1

TypeError: Cannot read property 'amountString' of undefined

發生這種情況是因爲您試圖解除未定義的值的引用。你基本上是寫作return sum + undefined.amountString,這與編寫return sum + null.amountString類似。你如何解決這個問題?

除了什麼的AgAlO建議,我們可以篩選那些僅具有成本jobTask對象:

json.data.forEach(function(item) { 

    var sum = item.jobTasks 
     .filter(function (j) { return j.cost; }) 
     .reduce(function(sum, elem) { 

     return sum + elem.cost.amountString; 

    }, 0); 

    console.log('jobNumber' + item.jobNumber + ' ' + sum); 

}); 

順便說一句,可以考慮使用箭頭語法,因爲它更易讀。

json.data.forEach((item) => { 

    var sum = item.jobTasks 
     .filter((j) => j.cost) 
     .reduce((sum, elem) => sum + elem.cost.amountString, 0); 

    console.log('jobNumber' + item.jobNumber + ' ' + sum); 

}); 

完整代碼列表:

var json = {}; 
 
json.data = [{ 
 
    "id": 100, 
 
    "jobNumber": 1, 
 
    "jobTasks": [{ 
 
     "id": 12, 
 
     "cost": { 
 
      "amountString": 100 
 
     } 
 
     }, 
 
     { 
 
     "id": 13, 
 
     "cost": { 
 
      "amountString": 500 
 
     } 
 
     } 
 
    ] 
 
    }, 
 
    { 
 
    "id": 101, 
 
    "jobNumber": 2, 
 
    "jobTasks": [{ 
 
     "id": 14, 
 
     "cost": { 
 
      "amountString": 100 
 
     } 
 
     }, 
 
     { 
 
     "id": 15 
 
     } 
 
    ] 
 
    } 
 
]; 
 

 
// with traditional functions 
 
json.data.forEach(function(item) { 
 

 
    var sum = item.jobTasks 
 
    .filter(function(j) { 
 
     return j.cost; 
 
    }) 
 
    .reduce(function(sum, elem) { 
 

 
     return sum + elem.cost.amountString; 
 

 
    }, 0); 
 

 
    console.log('jobNumber' + item.jobNumber + ' ' + sum); 
 

 
}); 
 

 
// with arrow functions 
 
json.data.forEach((item) => { 
 

 
    var sum = item.jobTasks 
 
    .filter((j) => j.cost) 
 
    .reduce((sum, elem) => sum + elem.cost.amountString, 0); 
 

 
    console.log('jobNumber' + item.jobNumber + ' ' + sum); 
 

 
});

+1

謝謝! - 這也有幫助! –