简体   繁体   中英

Find a coordinate in a multidimensional array using string search

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)%8),pos%10) // fails, how to fix? pos = string.indexOf("M") console.log(Math.floor((pos/10)%8),pos%10) 

 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] 

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); 

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] 

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 4 s 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.

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, '-')) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM