4

I am trying to make a small node application that lets me convert text to double-struck "letters". I am fairly new to JavaScript, and I was wondering what the best way to do this?

I could use: string.replace("A", doublestruck.uppercase.A) (see below) 62 (26 uppercase, 26 lowercase, 10 number), but I feel like there is definitely a better way to do this.

// specialcharacters.js
const doubleStruckUpper = {
        A: "", B: "", C: "ℂ", D: "", E: "",
        F: "", G: "", H: "ℍ", I: "", J: "",
        K: "", L: "", M: "", N: "ℕ", O: "",
        P: "ℙ", Q: "ℚ", R: "ℝ", S: "", T: "",
        U: "", V: "", W: "", X: "", Y: "",
        Z: "ℤ"
    };
const doubleStruckLower = { ... };
const doubleStruckNumbers = { ... };

module.exports.doubleStruck = {
    uppercase: doubleStruckUpper,
    lowercase: doubleStruckLower,
    numbers: doubleStruckNumbers,
};

// index.js

const { doubleStruck } = require("./specialcharacters");

var string = "Change this to double-struck characters";

string
    .replace("A", doubleStruck.uppercase.A)
    .replace("B", doubleStruck.uppercase.B)
    // and so on

This would work, but it would have to be so long and there is probably a better way to do this.

Thanks in advance!

Ben Richeson
  • 63
  • 2
  • 3
  • There are improvements which most definately can be done. Essentially, You are running at a O(N) of StringLength * 26. It can be improved to just Stringlength though – Fallenreaper Jul 18 '19 at 16:20
  • `Object.keys(doubleStruck).forEach(key => Object.keys(doubleStruck[key]).forEach(k => string.replace(new RegExp(k, 'g'), doubleStruck[key][k])))` – Heretic Monkey Jul 18 '19 at 16:22

3 Answers3

7

.replace lets you use a function:

const doubleStruckUpper = {
        A: "", B: "", C: "ℂ", D: "", E: "",
        F: "", G: "", H: "ℍ", I: "", J: "",
        K: "", L: "", M: "", N: "ℕ", O: "",
        P: "ℙ", Q: "ℚ", R: "ℝ", S: "", T: "",
        U: "", V: "", W: "", X: "", Y: "",
        Z: "ℤ"
    };

var string = "CHANGE THIS TO DOUBLE STRUCK LETTERS";

var result = string.replace(/[A-Z]/g, matchedLetter => doubleStruckUpper[matchedLetter]);

console.log(result);

Combined with a regex, you can find and match all desired characters and replace them, one by one, with the desired character. Since you've already created character maps, this should be a fairly fast and easy process, though I would recommend combining your character maps into a single map to make it faster and simpler.

JDB
  • 25,172
  • 5
  • 72
  • 123
0

Another example is to map each character in the string to double struck. If you don't need to keep double struck characters in 3 different maps, I would recommend merging them into a single map (eg: doubleStruckAll), then you can simply map as below:

var string = "Change this to double-struck characters";

const result = [...string].map(letter => {
    const replaced = doubleStruckAll[letter];
    return replaced ? replaced : letter;
}).join('')

console.log(result);

The code above spreads the string into an array of characters, then maps each character to double struck (if entry is present in double struck, then returns replaced character, otherwise returns original). Then it joins the new array back into a string.

Kon
  • 4,023
  • 4
  • 24
  • 38
0

ES6/ES2015 introduced a way to represent Unicode points in the astral planes (any Unicode code point requiring more than 4 chars), by wrapping the code in graph parentheses.

const unicodePoints = {
  A: '\u{1D538}',
  B: '\u{1D539}',
  C: '\u{2102}',
  D: '\u{1D53B}',
  E: '\u{1D53C}',
  F: '\u{1D53D}',
  G: '\u{1D53E}',
  H: '\u{210D}',
  I: '\u{1D540}',
  J: '\u{1D541}',
  K: '\u{1D542}',
  L: '\u{1D543}',
  M: '\u{1D544}',
  N: '\u{2115}',
  O: '\u{1D546}',
  P: '\u{2119}',
  Q: '\u{211A}',
  R: '\u{211D}',
  S: '\u{1D54A}',
  T: '\u{1D54B}',
  U: '\u{1D54C}',
  V: '\u{1D54D}',
  W: '\u{1D54E}',
  X: '\u{1D54F}',
  Y: '\u{1D550}',
  Z: '\u{2124}'
};

console.log("CHANGE THIS TO DOUBLE STRUCK LETTERS".replace(/[A-Z]/g, el => unicodePoints[el].normalize()));

You could could use this as an alternative to using the literal Unicode characters in your map.

Tom O.
  • 5,730
  • 2
  • 21
  • 35