0

I'm trying to solve a task. I know is quite basic as i'm just starting and studying for tech interview for a bootcamp. I'd be really grateful if someone could help me understand some whys. The following code should work adding my own method. It's a beginner excercise for getting an average. I could have done it with a for loop maybe, but i was trying to implement the reduce method.

This is the given code


var arr = [1, 2, 3, 4, 5];
var avg = arr.average();
console.log(avg);

I've been able to get the average with the following code.


var arr = [1, 2, 3, 4, 5];
function average() {
  const accPlusCur =(acc,cur) => acc + cur;
  const sumOfAll = arr.reduce(accPlusCur);
  return sumOfAll / arr.length;
};
console.log(average());
// => 3

The problem is i'm not really using exactly the given code. So i re wrote it this other way to try to have a function that i could apply to any array and not just this specific one. But it is not working.


var arr = [1, 2, 3, 4, 5];
function average(arrayName) {
  const accPlusCur = (acc,cur) {return acc + cur}, 0;
  const sumOfAll = arrayName.reduce(accPlusCur);
  return sumOfAll / arrayName.length;
};
const avg = average();
console.log(avg);

The solution given online is the following. Although i don't really quite get it.


Array.prototype.average = function() {
  var sum = this.reduce(function(prev, cur) { return prev + cur; });
   return sum / this.length;
}

var arr = [1, 2, 3, 4, 5];
var avg = arr.average();
console.log(avg); // => 3

Could someone please help me? Why is my second try not working as my first option did. What's the thing with this prototype method and the constatnt use of "this". Whi is Array word before prototype?

rodspain
  • 55
  • 10
  • what's the error ? – joyBlanks Oct 14 '19 at 03:50
  • 1
    Just as a side note: [why-is-extending-native-objects-a-bad-practice](https://stackoverflow.com/questions/14034180/why-is-extending-native-objects-a-bad-practice). Here, the solution does this by just assignment, and not even e.g. being non-enumerable. – ASDFGerte Oct 14 '19 at 03:52
  • I can see 3 problems, 1. accPlusCur keyword function is missing, 2. it ends with an unknown number 0, 3. you need to pass arr as argument as you are requesting an argument – joyBlanks Oct 14 '19 at 03:53
  • When an answer solves your problem, you may consider marking it as Accepted (check the checkbox on the left) to indicate that the issue is resolved :) – CertainPerformance Oct 14 '19 at 07:00

2 Answers2

1

In Javascript, objects (generally) have an internal prototype. Any property or method available on the property is also available on the object. For example, arrays have a .join method on the prototype: Array.prototype.join. So, you can call .join on any array, eg

myArray.join('')

despite the fact that join is not actually a property of the array - it's a property of the internal prototype of the myArray.

Similarly, by putting a function on the prototype, that function can be called by any instance.

When inside a prototype method, this references the object the method has been called on. So, eg, with

myArray.join('')

when .join is called, this inside it refers to myArray.

In the solution, the code

var sum = this.reduce(function(prev, cur) { return prev + cur; });

calculates the sum of the array that the method was called on. Since the method is on Array.prototype, any array will have access to that method.

The problem with your code:

var arr = [1, 2, 3, 4, 5];
function average(arrayName) {
  const accPlusCur = (acc,cur) {return acc + cur}, 0;
  const sumOfAll = arrayName.reduce(accPlusCur);
  return sumOfAll / arrayName.length;
};
const avg = average();
console.log(avg);

is that average accepts a parameter (the array you want to get an average from), but you aren't passing it one.

Also, the initial value for the accumulator should be the second parameter you pass to .reduce:

var arr = [1, 2, 3, 4, 5];
function average(arrayName) {
  const accPlusCur = (acc,cur) => acc + cur;
  const sumOfAll = arrayName.reduce(accPlusCur, 0);
  return sumOfAll / arrayName.length;
}
const avg = average(arr);
console.log(avg);
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
0

Thanks for taking the time to help. I really appreciate it. So now i understand the .this As for the prototype given answer if i understand correctly the following prototype function would be kind of declarina a function

Array.prototype.average = function() {
  // calculate sum
  var sum = this.reduce(function(prev, cur) { return prev + cur; });
  // return sum divided by number of elements
  return sum / this.length;
}

And afterwards it is called by

var avg = arr.average();

Is that correct?

As for the second approach i was trying i realized what i was doing wrong just a minute ago before checking this answer. And now this code is working perfectly fine.


const arr = [1, 2, 3, 4, 5];
function average(x) {
  const sumOfAll = x.reduce((acc, cur) => acc + cur, 0);
  return sumOfAll / x.length;
};
const averageVariable = average(arr); 
console.log(averageVariable);

Again, Thanks a lot for all your help and for dedicating time to help begginners. I'll do the same one day when i get better at this.

rodspain
  • 55
  • 10