0

Summary

I've been trying so solve this via an array that holds the Unicode codepoint table, but it is so large I am getting memory errors.

Details of my effort so far

I am using Typescript in combination with a Micro:Bit. I have a large array (128 entries) that is necessary for my program. This array stores various hex representations of the unicode table:

let font: number[] = [0x000b6526, 0x010514bf, 0x0004d6b2, 0x0010fc21, 0x0007c20f,
  0x00744107, 0x01f4111f, 0x000d909b, 0x00117041, 0x0008ceb9, 0x0008c7e0, 0x01041041, .......];

However, storing this array on the Micro:bit results in an 021 error (No free memory or too many objects in GC). Is there any alternative that I have missed to store this array? Further on in my program I need to use this array as a lookup table to convert chars of a string into their corresponding unicode characters:

let character = font[string.charCodeAt(stringPosition)]

Any ideas or suggestions on how to solve this memory issue, or is there a better way to achieve my aim as stated in the title of this question?

Inigo
  • 12,186
  • 5
  • 41
  • 70
Jxns
  • 19
  • 3
  • How is 128 entires large? In any case, you can't store an array of binary data any more efficiently than as an numeric array as you are doing. You could possibly use a lower level array (developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays). BUT, why are you doing this? Why don't you use the built-in Javascript facilities to convert to Unicode codepoints? – Inigo Jul 06 '21 at 15:17
  • I am writing a library for a display. To display springs on it, I need to transfer the corresponding unicodes to it. But I was also very confused to run out of space that quickly. I will try the lower level array. Thank you. – Jxns Jul 06 '21 at 15:17
  • I spent time on this to help you, so can you please tell me why you have to use an array and not use the built-in function to do this for you *for free* and certainly FAR more efficiently? (see my answer) Am I correct that the underlying problem is "How can I efficiently convert characters to their Unicode codepoint?" – Inigo Jul 06 '21 at 23:22
  • The problem is that I need to have the exact representation from above (e.g. 0x00117041) to transfer it to my display. And as far as I know there is no function "codePointAt()" in MakeCode. Do you have a suggestion for this? – Jxns Jul 07 '21 at 08:06
  • `codePointAt` is a method on `string`, it is built-in to Javascript. And it would be trivial to convert the decimal codepoint to the hex form you need. Trivial. So it sounds like you are admitting the array isn't critical, that simply you need to get the hex codepoints for any Unicode char, correct? – Inigo Jul 07 '21 at 08:08
  • Yes, thats exactly what I need. codePointAt is build-in to Javascript, but MakeCode is using Typescript. I have not found this function there? – Jxns Jul 07 '21 at 08:16
  • Typescript *is* Javascript! Have you tried the code in my answer? – Inigo Jul 07 '21 at 08:17
  • Yes I did. But it just gives me: Property 'codePointAt' does not exist on type 'string'. – Jxns Jul 07 '21 at 08:20
  • OK, it looks like you are not using ES6 (aka Ecmascript 2015). See [String.prototype.codePointAt() | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt). In your tsconfig, what is `target`? – Inigo Jul 07 '21 at 08:26
  • The target is set to "es5". Should I change this? – Jxns Jul 07 '21 at 08:28
  • Yes. Change it to `ES2015` and try my code again. – Inigo Jul 07 '21 at 08:33
  • I am still getting the same error. I have not found the tsconfig directly in the MakeCode environment. I changed it in my GitHub repository and pulled the repo again in MakeCode. Maybe the tsconfig is not loaded by MakeCode? – Jxns Jul 07 '21 at 08:40
  • Possibly. You have two options: figure out how to configure your build/environment to use ES2105, or just copy the Polyfill in the MDN link I shared above. Do you know what a Polyfill is? – Inigo Jul 07 '21 at 08:43
  • No, I haven't heard of polyfills before. – Jxns Jul 07 '21 at 08:46
  • A polyfill is code to back-port new Browser/Javascript functionality to older versions of the browser or Javascript. In any case, as explained in my updated answer, you can use the Polyfill method instead. – Inigo Jul 07 '21 at 08:53
  • Is it correct that I just need to copy the Polyfill into my code? I tried this but this also throws a lot of errors: `Zeile 310: Property 'prototype' does not exist on type 'typeof String'. Zeile 317: Property 'defineProperty' does not exist on type 'typeof Object'. Zeile 322: Parameter 'position' implicitly has an 'any' type. Zeile 324: Cannot find name 'TypeError'. Zeile 353: Property 'prototype' does not exist on type 'typeof String'. Zeile 359: Property 'prototype' does not exist on type 'typeof String'.` – Jxns Jul 07 '21 at 08:56
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/234607/discussion-between-inigo-and-jxns). – Inigo Jul 07 '21 at 09:08

1 Answers1

0

I highly suspect this is a case of the XY Problem, and that your real question is:

"How can I efficiently convert characters to their Unicode codepoint?"

If I am right, here is your solution. Replace your array and lookup with:

let s = 'a  right now would be nice.'
let stringPosition = 2 // third char
let character = s.codePointAt(stringPosition)  // 129347, the secret code for a stiff drink

codePointAt is a new ES6 method on string. It will be available in Typescript if your tsconfig has ES2015 (aka ES6) as the value for target.

If you are unable to switch to ES6 or later, then you can use the Polyfill given in the MDN article on codePointAt by copying the function to your code.

Inigo
  • 12,186
  • 5
  • 41
  • 70