0

I have an array with two values, (1 or 2) and (a, b, c or d). Depending on the two values a certain math function will execute. The function takes an separate inputted number and multiplies it by a constant, but that part isn't necessary to this.

Essentially a user provides the 3 values, I've already removed the one value which is the constant 'k', so I'm left with 2 values that determine the right multiplier for the constant 'k'.

I'm looking for something that would be easier and more robust than combining the array and running through all the possible solutions in a switch statement. There is a possibility of new variables for the array in the future.

let k = 5;
let input = [2, 'c'];

if (input.join().includes('1')) {
  if (input.join().includes('a')) {
    return k * 10;
  };
  else if (input.join().includes('b')) {
    return k * 11;
  };
  else if (input.join().includes('c')) {
    return k * 12;
  };
  else if (input.join().includes('d')) {
    return k * 13;
  };
};

else if (input.join().includes('2')) {
  if (input.join().includes('a')) {
    return k * 14;
  };
  else if (input.join().includes('b')) {
    return k * 15;
  };
  else if (input.join().includes('c')) {
    return k * 16;
  };
  else if (input.join().includes('d')) {
    return k * 17;
  };
};

Basically I have something like this right now. input and k are provided by the user, but not necessarily in any certain order, so I can't reliable assume input[1] will give me (a, b, c or d).

4
  • 1
    your post is unclear, add more information and code to help you further Commented Aug 5, 2017 at 2:56
  • 1
    Can you please show an example of what you're looking for? It's not really clear what the relationship is, or why you're doing this, and perhaps there's a way to avoid the issue completely if you explain the bigger picture a little better. So please edit and add an example of what you want, and also explain why you're doing this more thoroughly. Commented Aug 5, 2017 at 2:57
  • Are the numbers 10, 11, 12 just examples, or can they be anything else? Is it always a multiplication, or can it be any other operator? Can you provide the more generic rule, so we can see what is just example, and what is intended to be just like specified? Commented Aug 5, 2017 at 10:53
  • It will always be multiplication, just like k * 15. So in that example, 'k' is the user input and '15' is the constant that doesn't change. Commented Aug 5, 2017 at 18:36

3 Answers 3

1

I agree with Patrick's comment that there is a bit of mystery around what you're actually trying to do here. I also noticed your comment:

would I be able to add: var mathFuncs = { 1: 'one': { a: mathFunc10, b: mathFunc20 }

Are you saying you would like to be able to accept input values of 1 or one interchangeably?

You can do this very simply. The calculate() function below makes a copy of the input array with each element converted to a number if it is one of the number names, then sorts this array to put it in a consistent order (numbers sort before letters). Next, we select which list of multipliers to use (1 or 2), and finally get the specific multiplier (a-d) to calculate the return value. If the input array doesn't match anything, we return NaN.

const numbers = {
    'one': 1,
    'two': 2,
};

const multipliers = {
    1: { a:10, b:11, c:12, d:13 },
    2: { a:14, b:15, c:16, d:17 },
};

function calculate( k, input ) {
    const convert = n => numbers[ n.toString().toLowerCase() ] || n;
    const sorted = input.map( convert ).sort();
    const list = multipliers[ sorted[0] ];
    if( ! list ) return NaN;
    const multiplier = list[ sorted[1] ];
    return multiplier == null ? NaN : k * multiplier;
}

function test( k, input) {
    console.log( k, input.toString(), calculate( k, input ) );
}

test( 5, [ 1, 'a' ] );  // 50
test( 5, [ 'a', 1 ] );  // 50
test( 5, [ 'a', 'one' ] );  // 50
test( 5, [ 2, 'c' ] );  // 80
test( 5, [ 'two', 'c' ] );  // 80
test( 5, [ 2, 'e' ] );  // NaN
test( 5, [ 3, 'a' ] );  // NaN
test( 5, [ 'three', 'a' ] );  // NaN

Sign up to request clarification or add additional context in comments.

1 Comment

This is great! It works perfectly and it's really flexible incase I have to add any extra values. Thank you! (and I apologize about being unclear. I'm teaching myself all of this stuff, so I'm still really bad at vocalizing what it is I'm trying to do. Thank you for your understanding and help!)
1
var mathFunc = getMathFunc([2, 'b']);
mathFunc(2); // 80

function getMathFunc(arr) {
  var inputString = arr.join('');

  var mathFuncs = {
    1: {
      a: mathFunc10,
      b: mathFunc20
    },
    2: {
      a: mathFunc30,
      b: mathFunc40
    }
  };

  for (var numKey in mathFuncs) {
    if (inputString.includes(numKey)) {
      var numObj = mathFuncs[numKey];

      for (var letterKey in numObj) {
        if (inputString.includes(letterKey)) {
          return numObj[letterKey];
        }
      }
    }
  }

  function mathFunc10(num) {
    return 10 * num;
  }

  function mathFunc20(num) {
    return 20 * num;
  }

  function mathFunc30(num) {
    return 30 * num;
  }

  function mathFunc40(num) {
    return 40 * num;
  }
}

3 Comments

I see how the works, but what if I can't rely on arr[0] being the arrNum? Sometimes the first element is arrLetter. Also, would I be able to add: var mathFuncs = { 1: 'one': { a: mathFunc10, b: mathFunc20 } Or would that not work?
Cool! If the order of the elements in the array doesn't matter, then you were probably moving in the right direction originally, with something like: if (arr.includes(1) && arr.includes('a') { doSomething(); } else if (arr.includes(1) && arr.includes('b) { doSomethingElse(); } etc.
Right. But I will still have 8 if statements for this example, and if I add '3', then I have 12 if statements. Is there an easier way or is that one of the easiest ways?
1

If the logic of the returned value is like in your example, then this will do it:

const ref = { 1: 10, 2: 14, a: 0, b: 1, c: 2, d: 3 },
      calc = (k, input) => k * input.reduce( (res, x) => res + ref[x], 0 );

// Sample calls:
console.log([
    calc(5, [2, 'c']), // 80
    calc(5, ['c', 2]), // 80
    calc(5, ['a', 1]), // 50
    calc(5, [2, 'b']), // 75
    calc(5, [3, 'd']), // NaN
    calc(5, ['e', 2]), // NaN
]);

Of course, if the logic is more complex in other cases, then you'll have to implement that logic in your function and/or the proposed ref mapping object. If the "variables" are more interdependent, you may even need several mapping objects.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.