forty5
forty5

Reputation: 65

How not to check a value twice?

I have a function that performs some operations on a given symbol. But first it checks if the code of that symbol is in a specific range (to prevent errors):

function transformSpecialChar(char) {
   const shouldTransform = char.charCodeAt(0) > someNumber && char.charCodeAt(0) < someOtherNumber;
   if(shouldTransform) {
      // do something
      return transformed;
   }
   return undefined;
}

I also have a function stringToArray that breaks a given string into characters. Then if some character is special, it calls a transformSpecialChar function and passes that char as an argument. If the character is not special then the function does something else.

function stringToArray(str) {
    const result = Array.from(str);
 
    result = result.map(el => {
        const isSpecial = el.charCodeAt(0) > someNumber && el.charCodeAt(0) < someOtherNumber;
        if(isSpecial) {
            return transformSpecialChar(el)
        }

        // else do something else with a character
    })

    return result
}

The problem is that I check the character twice. First when I check what kind of operation should a stringToArray function perform on an other character of a given string. And then I check the character again inside transformSpecialChar function to make sure that the given char could be transformed as it has to. I can't drop that check process from the transformSpecialChar function since this function is used not only in stringToArray and it should always check the given char to avoid unexpected errors. And I also can't drop that check process form the stringToArray function because different types of characters should be processed differently.

I tried to drop the check process from the stringToArray function and see if transformSpecialChar function returns undefined.

function stringToArray(str) {
    const result = Array.from(str);
 
    result = result.map(el => {
        const transformed = transformSpecialChar(el);

        if (transformed) {
            return transormed
        }
        

        // else do something else with a character
    })

    return result
}

But in this case the transform function is run for every character in a string and it seems super inefficient.

Upvotes: 0

Views: 92

Answers (1)

KooiInc
KooiInc

Reputation: 122898

Make transformSpecialChar a factory function to use for either mapping an Array of characters, or as a stand alone function. Something like:

const str = `{Some string with speçíal charäcters}`;
console.log(`Original string: ${str}`);

// note: undefined will map to null and will not be
// included in `join`
console.log(`stringToArray(str).join(\`\`) => ${
  stringToArray(str).join(``)}`);
console.log(`stringToArray(str, true).join(\`\`) => ${
  stringToArray(str, true).join(``)}`);

// use the factory as stand alone function
const transformer = transformSpecialChar(false);
console.log(`transformer(\`4\`) => ${transformer(`4`)}`);
console.log(`transformer(\`A\`) => ${transformer(`A`)}`);

// This factory function returns a function 
// to be used in Array.map or stand alone. 
// It uses [returnValues] from closure
function transformSpecialChar(returnValues = false) {
   return chr => {
    const chrCode = chr.charCodeAt(0);
    return chrCode > 200 || chrCode < 62 ? 
      `#${chrCode};` : (returnValues && chr || undefined);
    };
}

function stringToArray(str, includeNotTransformed = false) {
    return [...str].map(transformSpecialChar(includeNotTransformed));
}

Upvotes: 1

Related Questions