-3

Try to give an alternative in this question WITHOUT LOOPING! Just using indexOf and some integer math

Get coordinates of an element in multidimentional array in Javascript

The code below seemed promising but fails.

Anyone with better math skills feel like fixing it?

var letterVariations = [ 
        [' ','0','1','2','3','4','5','6','7','8','9'],
        ['A','a','B','b','C','c','D','d','E','e',';'],
        ['Â','â','F','f','G','g','H','h','Ê','ê',':'],
        ['À','à','I','i','J','j','K','k','È','è','.'],
        ['L','l','Î','î','M','m','N','n','É','é','?'],
        ['O','o','Ï','ï','P','p','Q','q','R','r','!'],
        ['Ô','ô','S','s','T','t','U','u','V','v','“'],
        ['W','w','X','x','Y','y','Ù','ù','Z','z','”'],
        ['@','&','#','[','(','/',')',']','+','=','-'],
    ];

var string = JSON.stringify(letterVariations);
var pos = string.indexOf("u")
console.log(Math.floor((pos/10)%9),pos%10)

// fails, how to fix?
pos = string.indexOf("M")
console.log(Math.floor((pos/10)%9),pos%10)

17
  • What are you trying to do with "% 8"? Commented Mar 13, 2019 at 15:49
  • JSON.strinigfy gives you string like [[" ","0","1","2","3","4","5","6","7","8","9"],["A","a","B","b","C","c","D","d","E","e",";"]..., you can't search here, it's better to use letterVariations.toString() Commented Mar 13, 2019 at 15:49
  • 1
    Well, that's an 11 x 9 grid, not 10 x 8. Commented Mar 13, 2019 at 15:58
  • 1
    For the x position, I think you can try to proportionate the value to the length of the string. Example: u has index 307, using: Math.floor((pos*11)/string.length) you can get the x position, which is 8 in that case. It's 11 because it's an 11x9 grid. I'm not sure how you can get the Y value though. Commented Mar 13, 2019 at 16:00
  • 1
    @AlexOwl mind explaining why? JSON.stringify does not add things arbitrarely and, since the length of each item of the array is always the same, you should be able to get informations back. Besides, I think the original question is to fix the code he provided by keeping the logic of what is currently written. Commented Mar 13, 2019 at 16:05

5 Answers 5

2

function findPos(array, symbol) {
  const string = array.toString().replace(/,/g, '');
  const pos = string.indexOf(symbol)

  const d = (array[0] || []).length

  const x = pos % d;
  const y = Math.floor(pos / d)

  return { x, y }
}

const array = [
  [' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
  ['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', ';'],
  ['Â', 'â', 'F', 'f', 'G', 'g', 'H', 'h', 'Ê', 'ê', ':'],
  ['À', 'à', 'I', 'i', 'J', 'j', 'K', 'k', 'È', 'è', '.'],
  ['L', 'l', 'Î', 'î', 'M', 'm', 'N', 'n', 'É', 'é', '?'],
  ['O', 'o', 'Ï', 'ï', 'P', 'p', 'Q', 'q', 'R', 'r', '!'],
  ['Ô', 'ô', 'S', 's', 'T', 't', 'U', 'u', 'V', 'v', '“'],
  ['W', 'w', 'X', 'x', 'Y', 'y', 'Ù', 'ù', 'Z', 'z', '”'],
  ['@', '&', '#', '[', '(', '/', ')', ']', '+', '=', '-'],
];


console.log(findPos(array,' ')) //=> [0, 0]
console.log(findPos(array,'M')) //=> [4, 4]
console.log(findPos(array,'u')) //=> [6, 7]
console.log(findPos(array,'-')) //=> [8, 10]

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

3 Comments

What happens if one of the entries is more than one character?
@MarkMeyer it brokes) You need to use normal solution like above to handle such cases
Oh, ok, that's interesting. Mind explaining how X and Y are calculated? That answers the question anyway. Of course, elements with more than one character would break the algorithm but still, I think this answers the question.
2

You could join the strings and use the length of the inner array as value for divisioin or for the remainder operator. This works only for strings with a single character.

var letterVariations = [
        [' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
        ['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', ';'],
        ['Â', 'â', 'F', 'f', 'G', 'g', 'H', 'h', 'Ê', 'ê', ':'],
        ['À', 'à', 'I', 'i', 'J', 'j', 'K', 'k', 'È', 'è', '.'],
        ['L', 'l', 'Î', 'î', 'M', 'm', 'N', 'n', 'É', 'é', '?'],
        ['O', 'o', 'Ï', 'ï', 'P', 'p', 'Q', 'q', 'R', 'r', '!'],
        ['Ô', 'ô', 'S', 's', 'T', 't', 'U', 'u', 'V', 'v', '“'],
        ['W', 'w', 'X', 'x', 'Y', 'y', 'Ù', 'ù', 'Z', 'z', '”'],
        ['@', '&', '#', '[', '(', '/', ')', ']', '+', '=', '-']
    ],
    string = letterVariations.map(a => a.join('')).join(''),
    pos = string.indexOf("u");

console.log(Math.floor(pos / 11), pos % 11);

pos = string.indexOf("M")
console.log(Math.floor(pos / 11), pos % 11);

4 Comments

Is your map not a variation on stringify?
Why is there an overhead compared to map?
the stringified versiopn has quotes, commas and brackets, which generates an overhead of characters for getting the position and calculate the indices.
There are also some (likely unimportant, but real) performance advantages: measurethat.net/Benchmarks/Show/4740
1

Here is one version of that:

var letterVariations = [ 
  [' ','0','1','2','3','4','5','6','7','8','9'],
  ['A','a','B','b','C','c','D','d','E','e',';'],
  ['Â','â','F','f','G','g','H','h','Ê','ê',':'],
  ['À','à','I','i','J','j','K','k','È','è','.'],
  ['L','l','Î','î','M','m','N','n','É','é','?'],
  ['O','o','Ï','ï','P','p','Q','q','R','r','!'],
  ['Ô','ô','S','s','T','t','U','u','V','v','“'],
  ['W','w','X','x','Y','y','Ù','ù','Z','z','”'],
  ['@','&','#','[','(','/',')',']','+','=','-'],
];

const findLetterIn = letterVariations => {
  const width = letterVariations[0].length * 4 + 2;
  const alpha = JSON.stringify(letterVariations)

  return (char, pos = alpha.indexOf(char)) => pos > -1 
    ? [Math.floor((pos - 1) / width), (((pos - 1) % width) - 2)/4]
    : [-1, -1]
}

const findLetter = findLetterIn (letterVariations)

console.log(findLetter(' ')) //=> [0, 0]
console.log(findLetter('M')) //=> [4, 4]
console.log(findLetter('u')) //=> [6, 7]
console.log(findLetter('-')) //=> [8, 10]

Here width has to do with row width.

The 4s have to do with u ~> "u", The + 2 has to do with adding [ and ] to the beginning and end (as well as an additional , after the ], but removing one before it.) The - 1 has to do with ignoring the initial [ and the - 2 has to do with removing the leading ," or, for the first one, the leading [".

You can switch to 1-based indices by adding 1 to both element of the returned array.

Comments

1

This produces the correct result. There is no need to stringify, you can flatten the arrays and use indexOf to get the position:

var letterVariations = [
  [' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
  ['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', ';'],
  ['Â', 'â', 'F', 'f', 'G', 'g', 'H', 'h', 'Ê', 'ê', ':'],
  ['À', 'à', 'I', 'i', 'J', 'j', 'K', 'k', 'È', 'è', '.'],
  ['L', 'l', 'Î', 'î', 'M', 'm', 'N', 'n', 'É', 'é', '?'],
  ['O', 'o', 'Ï', 'ï', 'P', 'p', 'Q', 'q', 'R', 'r', '!'],
  ['Ô', 'ô', 'S', 's', 'T', 't', 'U', 'u', 'V', 'v', '“'],
  ['W', 'w', 'X', 'x', 'Y', 'y', 'Ù', 'ù', 'Z', 'z', '”'],
  ['@', '&', '#', '[', '(', '/', ')', ']', '+', '=', '-'],
];

var flattened = letterVariations.flat()

var findLetter = function(letter) {
  var pos = flattened.indexOf(letter),
    x = Math.floor((pos / 10) % 8),
    y = (pos - (pos % 11)) / 11;
  return {
    letter: letter,
    x: x,
    y: y
  }
}
console.log(findLetter(' ')) //=> [0, 0]
console.log(findLetter('M')) //=> [4, 4]
console.log(findLetter('u')) //=> [6, 7]
console.log(findLetter('-')) //=> [8, 10]

1 Comment

It fails on the last char
0

Based on @GluePear answer

You can even use multi-chars in this solution

function findPos(array, symbol) {
  const string = array.flat();
  const pos = string.indexOf(symbol)
  
  const d = (array[0] || []).length
  
  const x = pos % d;
  const y = Math.floor(pos / d)

  return { x, y }
}

const array = [ 
		[' ','0','1','2','3','4','5','6','7','8','9'],
		['A','a','B','b','C','c','D','d','E','e',';'],
		['Â','â','F','f','G','g','H','h','Ê','ê',':'],
		['À','à','I','i','J','j','K','k','È','è','.'],
		['L','l','Î','î','M','m','N','n','É','é','?'],
		['O','o','Ï','ï','P','p','Q','q','R','r','!'],
		['Ô','ô','S','s','T','t','U','u','V','v','“'],
		['W','w','X','x','Y','y','Ù','ù','Z','z','”'],
		['@','&','#','[','(','/',')',']','+','=','-'],
	];
  
  
console.log(findPos(array, '-'))

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.