dharani
dharani

Reputation: 21

How to call a object method on an array?

I am using math.js and I want to call the method addFive on every element of the array x. If I call addFive on a variable like y, it works fine. I get an output of 10.

x = math.matrix([2,3,4]);
let y= 5;
function example(){
    this.a=5;
    this.addFive = function(x){
        return (x+this.a);
    }
}
ex = new example();
let w = ex.addFive(y);
console.log(w);

when I tried this,

let w = math.map(x, addFive);
console.log(w);

I am getting an error that addFive is not defined. is there a way around this without using loops?

Upvotes: 0

Views: 113

Answers (4)

jo_va
jo_va

Reputation: 13993

You have to pass the function as ex.addFive since addFive is only defined in your ex object.

Also, you must bind the function to ex to pass the right context for this.a to work inside the method.

Note that you can also use matrix.map(fn) instead of math.map(matrix, fn). Combined with an arrow function defined inline, this simplifies to:

console.log(math.matrix([2, 3, 4]).map(x => x + 5));

Here is an example:

function example() {
    this.a = 5;
    this.addFive = function (x) {
        return x + this.a;
    }
}
const ex = new example();

console.log(ex.addFive(5));
console.log(math.matrix([2, 3, 4]).map(ex.addFive.bind(ex)).toString());
console.log(math.map(math.matrix([2, 3, 4]), ex.addFive.bind(ex)).toString());
console.log(math.matrix([2, 3, 4]).map(x => x + 5).toString());
<script language="JavaScript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.8.0/math.min.js"></script>

Upvotes: 2

VLAZ
VLAZ

Reputation: 29115

Assuming math.map will take an array (or matrix) as the first parameter and a function to run against each as the second, then you need to pass a function. Right now addFive is a method defined on the instance of example objects. So, you first need to create one object to be able to access that code

let ex = new example();

Next you need to pass a code that calls ex.addFive

let w = math.map(x, item => ex.addFive(item));

x = math.matrix([2,3,4]);

function example(){
    this.a=5;
    this.addFive = function(x){
        return (x+this.a);
    }
}

ex = new example();

let w = math.map(x, item => ex.addFive(item));
console.log(w);
<script src=https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.3.0/math.min.js></script>

this way you run ex.addFive against each item in this matrix

Do note that you can also pass the reference to addFive directly but you'll run into an error

math.map(x, ex.addFive)

x = math.matrix([2,3,4]);

function example(){
    this.a=5;
    this.addFive = function(x){
        return (x+this.a);
    }
}

ex = new example();

let w = math.map(x, ex.addFive);
console.log(w);
<script src=https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.3.0/math.min.js></script>

This is because the this context would be lost when .map executes the callback and addFive uses this.a. You can preserve the context by using .bind()

math.map(x, ex.addFive.bind(ex))

x = math.matrix([2,3,4]);

function example(){
    this.a=5;
    this.addFive = function(x){
        return (x+this.a);
    }
}

ex = new example();

let w = math.map(x, ex.addFive.bind(ex));
console.log(w);
<script src=https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.3.0/math.min.js></script>

This is an alternative to passing a callback like the previous one item => ex.addFive(item) - the two are equivalent and it matters little which one you pick. I personally dislike using .bind in this case because you already have ex.bind only to follow it with .bind(ex). It looks a bit ridiculous.

Another alternative is to change the functionality - you only need to establish the context of the function, if uses this if you change example to

function example(){
    this.addFive = function(x){
        return (x+5);
    }
}

then there is no usage of this which means that you can call math.map(x, ex.addFive) and get the correct result.

x = math.matrix([2,3,4]);

function example(){
    this.addFive = function(x){
        return (x+5);
    }
}

ex = new example();

let w = math.map(x, ex.addFive);
console.log(w);
<script src=https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.3.0/math.min.js></script>

Upvotes: 1

Mark
Mark

Reputation: 92461

Since addFive is a method on an instance, you need to call it through the instance. You can do this by calling ex.addFive() instead of the bare addFIve() which isn't defined as a standalone function.

x = math.matrix([2,3,4]);

function example(){
    this.a=5;
    this.addFive = function(x){
        return (x+this.a);
    }
}

ex = new example();

let w = math.map(x, (n) => ex.addFive(n));
console.log(w);
<script src=https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.3.0/math.min.js></script>

Of course, if you are just making this object to use an addFive() method, you are probably better off just defining it as a function, which will make everything simpler:

x = math.matrix([2,3,4]);

const addFive = (x) => x + 5

let w = math.map(x, addFive);
console.log(w);
<script src=https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.3.0/math.min.js></script>

Upvotes: 2

sem
sem

Reputation: 61

addFive is a function that requires one input in it. try to use

let w = math.map(x, addFive(5));
console.log(w);

Upvotes: -3

Related Questions