0

I have this function to set the movement of cubes on the canvas (random), everyVar is the variables that will be used and a,b,c,d are functions for +,-,*,/ (sorry if its confusing). Is there a way to find the name of the variable instead of the value it holds; I have "user.s = a(b(c(d(r, 2), e), w), q);" and i need a way to put that in a repeating function so that the variables stay the same but the information updates, but if i put it somewhere else as it is it will have different variables. I cant just set another variable like myVariable = q because it will save the number not the variable itself (i need it to say user.y instead of 300 for example). Please make your answer as simple as possible as I am a beginner as you can probably tell.

function setMovement(user){
    var everyVar = [user.x, user.y, user.direction, user.distance]

    var q = everyVar[Math.floor(Math.random()*everyVar.length)];
    var w = everyVar[Math.floor(Math.random()*everyVar.length)];
    var e = everyVar[Math.floor(Math.random()*everyVar.length)];
    var r = everyVar[Math.floor(Math.random()*everyVar.length)];

    user.s = a(b(c(d(r, 2), e), w), q);

    a = operators[Math.floor(Math.random()*operators.length)]
    b = operators[Math.floor(Math.random()*operators.length)]
    c = operators[Math.floor(Math.random()*operators.length)]
    d = operators[Math.floor(Math.random()*operators.length)]
}
Suren Srapyan
  • 66,568
  • 14
  • 114
  • 112
  • hope this will help: http://stackoverflow.com/questions/22548885/print-display-a-javascript-variables-name-instead-of-its-value – James Oct 29 '16 at 07:05
  • I must admit that the question in the title and the description seems a bit disconnected from each other. The title question asks about getting variable names - which James posted an excellent link showing how you could solve that part. But the description it seems you want to put a function on user.s to have the transformations available to be called outside the function, and point to the values passed to the setMovement function. if that is the case you can assign user.s to be a function, rather than an invocation to store the function on the user object, and call it at will. – Espen Oct 29 '16 at 07:43

2 Answers2

1

Here is some code you could use:

// Define the operators as functions
var operators = [
    function add(x, y) { return x + y },
    function sub(x, y) { return x - y },
    function mul(x, y) { return x * y },
    function div(x, y) { return x / y }
];

// Don't reference the values, but the property names
var everyVar = ['x', 'y', 'direction', 'distance'];

function setMovement(user){
    var q = everyVar[Math.floor(Math.random()*everyVar.length)];
    var w = everyVar[Math.floor(Math.random()*everyVar.length)];
    var e = everyVar[Math.floor(Math.random()*everyVar.length)];
    var r = everyVar[Math.floor(Math.random()*everyVar.length)];

    var a = operators[Math.floor(Math.random()*operators.length)]
    var b = operators[Math.floor(Math.random()*operators.length)]
    var c = operators[Math.floor(Math.random()*operators.length)]
    var d = operators[Math.floor(Math.random()*operators.length)]

    // Make s a function, so the expression is evaluated with the
    // current values of the user object properties:
    user.s = function () {
        return a(b(c(d(user[r], 2), user[e]), user[w]), user[q]);
    };
    // For debugging, you can use this extra property to see
    // which expression the "random" function evaluates:    
    user.s.description = `${a.name}(${b.name}(${c.name}(${d.name}` +
                         `(user.${r}, 2), user.${e}), user.${w}), user.${q})`;
}

// same data
var user = {
    x: 20,
    y: 10,
    direction: 1,
    distance: 5
}
// Define "random" function user.s
setMovement(user);

console.log( 'user.s() evaluates this expression:\n', user.s.description );

console.log( 'result of user.s():', user.s() );

// Change x and y and display result then:
user.x -= 5; 
user.y += 10;
console.log( 'result of user.s():', user.s() );

NB: be careful with division: when the second argument is 0, you'll get a run-time error.

trincot
  • 317,000
  • 35
  • 244
  • 286
  • Yes this is what i was trying to get at with my comment, if you combine this answer with mine, and account for 0 division in the division function, you will get what you want. – Espen Oct 29 '16 at 07:57
  • @Espen, I would not want to use `Object.keys` as the `user` object may have (or get) other information that has nothing to do with the position or movement, such as the user's name. Also, it is up to the OP to decide how to deal with division by 0.. I just mentioned it as a warning. Maybe division is not such a good function candidate, or maybe division by zero should be replaced by some constant value, or maybe values are never expected to be zero,... and when they are, an exception should be raised. It all depends on expectations, and it is not really the issue raised in the question. – trincot Oct 29 '16 at 08:11
  • then I would move the array with the movement property names into the scope of the set movement function instead of closing over it to protect it. – Espen Oct 30 '16 at 13:01
0

I got it now trying to fiddle with your code. I believe what you are looking for is Object.keys()

function setMovement(user){
    var everyVar = Object.keys(user);

    var q = everyVar[Math.floor(Math.random()*everyVar.length)];
    var w = everyVar[Math.floor(Math.random()*everyVar.length)];
    var e = everyVar[Math.floor(Math.random()*everyVar.length)];
    var r = everyVar[Math.floor(Math.random()*everyVar.length)];

    user.s = a(b(c(d(r, 2), e), w), q);

    a = operators[Math.floor(Math.random()*operators.length)]
    b = operators[Math.floor(Math.random()*operators.length)]
    c = operators[Math.floor(Math.random()*operators.length)]
    d = operators[Math.floor(Math.random()*operators.length)]
}

Now you get all the properties of the user object as strings in an array, you can use them for assignment by using regular array index syntax:

var user = { x:10, y:20,direction:1,distance:10};
var everyVar = Object.keys(user);
var x = user[everyVar[1]];

Will assign 10 to the variable x

Espen
  • 2,456
  • 1
  • 16
  • 25