how is working this function? Dictionary ?

Hi,

I'd like to understand how a function is working.

I found it in a Watch Face example, a very interesting one, but i did not find any explanation in doc.

Where to search for ?

            var myVar= {
                    "A" => 65,
                    "B" => 66,
                    "C" => 67,
                    "D" => 68,
                }[someArray[1]].toChar().toString();

if someArray[1] is A , so myVar = 65

How is it working ??

(i understand the .toChar().toString(), the test between what's in someArray and the Dic, ...)

I am asking myself if i could change some "switch/if else" with this, but i'd like to understand well how it works.

Any idea where i could find it in the Docs?

thanks

  • It is not all that complicated if you break it down. Here is a simplified version...

    // Dictionary that maps from String to Number
    var CHAR_TO_ASCII = {
        "A" => 65,
        "B" => 66,
        "C" => 67,
        "D" => 68,
    };
    
    // use the 2nd element in someArray as the key. Presumably someArray is an array
    // of Strings where each element is one of the keys in myVar
    var charKey = someArray[1];
    
    // lookup the Number for the given String
    var myVar = CHAR_TO_ASCII[charKey];
    
    // convert that Number to a Char, and then to a String
    myVar = value.toChar();
    myVar = value.toString();

    The original code is possibly a little confusing because it uses an anonymous temporary Dictionary (named CHAR_TO_ASCII in my simplified version). If you give the temporary a name, it may make a little more sense to you.

    Of course you could use this trick to replace some switch or if/else statements, but if you're going to I'd recommend that you consider making the Dictionary a static (and probably const) class or a module variable so that the runtime doesn't re-create the dictionary every time the code is executed.

    You won't find this in the documentation anywhere because it is just using a Dictionary the way it is supposed to be used.

    That said, I don't really understand what the point of the code is in the first place. If someArray[1] is "A", this will do a Dictionary lookup and find the value 65 (the ASCII code for 'A'), then it will convert the Number with value 65 to the Char 'A', and then it will convert that Char to the String "A", which is what you started with in the first place. Maybe you omitted some of the Dictionary entries and this is just a trick for implementing toupper (in that case I'd expect to see mapping "a" => 65 which is actually doing something useful)?

    If this is an attempt to implement something like toupper, it may be worthwhile try doing something a little more tricky, maybe using a ByteArray to map from one ASCII code to another ASCII code, or maybe using some arithmetic like this:

    using Toybox.Test;
    using Toybox.System;
    using Toybox.Lang;
    
    const ASCII_A = 'A'.toNumber();
    const ASCII_Z = 'Z'.toNumber();
    
    const ASCII_a = 'a'.toNumber();
    const ASCII_z = 'z'.toNumber();
    
    function char_toupper(c)
    {
        var ascii_code = c.toNumber();
    
        if ( (ASCII_a <= ascii_code) && (ascii_code <= ASCII_z)) {
            ascii_code += (ASCII_A - ASCII_a);
        }
    
        return ascii_code.toChar();
    }
    
    function string_toupper(s)
    {
        // pretty sure this is not UTF-8 safe, but the other code isn't either
        var a = s.toCharArray();
    
        s = "";
    
        for (var i = 0; i < a.size(); ++i) {
            s += char_toupper(a[i]).toString();
        }
    
        return s;
    }
    
    (:test)
    module Testing {
    
        function do_test_char_toupper(logger, input, output)
        {
            var result = char_toupper(input);
    
            var message = Lang.format("given '$1$' expected '$2$', got '$3$'", [ input, output, result ]);
            if (! result.equals(output)) {
                logger.error(message);
                return false;
            } else {
                logger.debug(message);
                return true;
            }
        }
    
        function do_test_string_toupper(logger, input, output)
        {
            var result = string_toupper(input);
    
            var message = Lang.format("given \"$1$\" expected \"$2$\", got \"$3$\"", [ input, output, result ]);
            if (!result.equals(output)) {
                logger.error(message);
                return false;
            } else {
                logger.debug(message);
                return true;
            }
        }
    
        (:test)
        function test_char_toupper(logger)
        {
            var result = true;
    
            result = do_test_char_toupper(logger, 'A', 'A') ? result : false;
            result = do_test_char_toupper(logger, 'a', 'A') ? result : false;
            result = do_test_char_toupper(logger, '-', '-') ? result : false;
            result = do_test_char_toupper(logger, ' ', ' ') ? result : false;
    
            return result;
        }
    
        (:test)
        function test_string_toupper(logger)
        {
            var result = true;
    
            result = do_test_string_toupper(logger, ""   ,    "") ? result : false;
            result = do_test_string_toupper(logger, "A"  ,   "A") ? result : false;
            result = do_test_string_toupper(logger, "a"  ,   "A") ? result : false;
    
            result = do_test_string_toupper(logger, "ABC", "ABC") ? result : false;
            result = do_test_string_toupper(logger, "aBC", "ABC") ? result : false;
            result = do_test_string_toupper(logger, "AbC", "ABC") ? result : false;
            result = do_test_string_toupper(logger, "ABc", "ABC") ? result : false;
    
            return result;
        }
    }

  • thank ypu Travis.

    So, I have to take a deeper look at Dictionary.

    And, indeed, better make a const, since i use it for a font mapping, and was planning too to use it as a" toUpper "  for some UserSettings input !

    thank you again !