Reputation: 23
Running a test on my code. It should return 0 if the property passed into the function does not exist. But its not returning anything. Did I make a typo?
var obj = {
key: [1, 2, 3]
};
function getAverageOfElementsAtProperty(obj, key) {
if (obj[key].length === 0 || Array.isArray(obj[key]) === false || obj.hasOwnProperty(key) === false) {
return 0;
}
var average = 0;
for (var i = 0; i < obj[key].length; i++) {
average += obj[key][i];
}
average /= obj[key].length;
return average;
}
console.log(getAverageOfElementsAtProperty(obj, 'notKey'));
Upvotes: 0
Views: 2007
Reputation: 65806
If you don't pass an array to your function, it fails when it tries to get the length
of the object that was passed, so that shouldn't be how you test initially. You just need to see if the property exists and that is done by simply attempting to access the property in an if
condition.
Now, if you are going to add tests to see if the property does exist and that it is an array, then you have to add more tests to check the items in the array to see if they are numbers, otherwise trying to get a numerical average will fail.
Since there are really two things to do (check if the property is there and get math average), I would break this into two functions:
var obj1 = {
key: [1, 2, 3]
};
var obj2 = {
key: [1, "test", 3]
};
function getAverageOfElementsAtProperty(obj, key) {
if (obj[key] && Array.isArray(obj[key])) {
// Ok, we have the right property and there is an array there,
// now we have to test that each item in the array is a number
var numbers = obj[key].every(function (currentValue) {
return typeof currentValue === "number";
});
// Return the average if we have all numbers or 0 if not
return numbers ? getAverage(obj[key]) : 0;
} else {
return 0;
}
}
function getAverage(arr){
var average = 0;
// Array.forEach() is much simpler than counting loops
arr.forEach(function(item) {
average += item;
});
return average / arr.length;
}
console.log(getAverageOfElementsAtProperty(obj1, 'notkey')); // 0
console.log(getAverageOfElementsAtProperty(obj1, 'key')); // 2
console.log(getAverageOfElementsAtProperty(obj2, 'key')); // 0 - obj2 does not contain all numbers
Upvotes: 3
Reputation: 4406
Since obj['notKey']
does not exist, it does not return an array. Therefore you cannot do .length
of undefined. I would change it to typeof
to see if its defined or not.
var obj = {
key: [1, 2, 3]
};
function getAverageOfElementsAtProperty(obj, key) {
if (typeof obj[key] == 'undefined' || Array.isArray(obj[key]) === false || obj.hasOwnProperty(key) === false) {
return 0;
}
var average = 0;
for (var i = 0; i < obj[key].length; i++) {
average += obj[key][i];
}
average /= obj[key].length;
return average;
}
console.log(getAverageOfElementsAtProperty(obj, 'notKey'));
Upvotes: 1