简体   繁体   中英

Cleaner approach to find and replace in NodeJS?

I'm currently attempting to read a file, pass the contents and multiple arrays to the function; see if any of it matches using regex and then replace & finally update.

The code I've put together which looks ugly and clumpy is this:

find_and_replace: function(file, ...items) {
    let str = _.clone(file);
    let valid = {};
    let do_escape = true;
    let hit;
    if (items != null ? items.length : void 0) {
        for (let i = 0, len = items.length; i < len; i++) {
            let obj = items[i];
            try {
                for (k in obj) {
                    let v = obj[k];
                    if (valid[k] == null) {
                        valid[k] = v;
                    }
                }
            } catch (error) { }
        }
        try {
            str = str.replace('/{{([\s\S]+?)}}/g', function(a, b) {
                if (hit = valid[b]) {
                    if (do_escape) {
                        return escape(hit);
                    } else {
                        return hit;
                    }
                }
                return '';
            });
        } catch (error) {
            console.log(error);
        }
    }
    return str;
},

The use of the function is as follows:

for (let _i = 0, _len = files.length; _i < _len; _i++) {
    let x = files[_i];
    if(x.includes('node_modules')) {
        continue;
    }
    builder.find_and_replace(builder.read_file(x), main_config, second_config);
    break;
}

The functionality of this "system" is to find any {{tag}} placeholders from within the file & replace with the correct key from inside the ...items combined array

I'd greatly appreciate if anyone could point me in the right direction to lower the amount of code required.

Some simplification may include using Object.entries or Array.reduce methods

function find_and_replace(file, ...items) {
  let str = _.clone(file);
  let do_escape = true;
  let hit;

  if (items != null ? items.length : void 0) {
    const valid = items.reduce((valid, obj) => {
      Object.entries(obj)
        .map([k, v] => {
          valid[key] = v;
        });
      return valid;
    }, {});

    try {
      str = str.replace('/{{([\s\S]+?)}}/g', (a, b) => hit === valid[b] ? (do_escape ? escape(hit) : hit) : '');
    } catch (error) {
      console.log(error);
    }
  }
  return str;
},

When you use function rest parameters ( ...items ), you always get an array under items so if (items != null ? items.length : void 0) is redundant.

items.reduce((all, obj) => ({...all, ...obj}), {}) creates single object from ...items

(string, [key, value]) => string.replace(new RegExp(`{{${key}}}`, "gi"), value) will find all occurrences of keys from object and replace them with values

 const tr = (string, ...items) => "" + Object.entries(items.reduce((all, obj) => ({...all, ...obj}), {})).reduce((string, [key, value]) => string.replace(new RegExp(`{{${key}}}`, "gi"), value), string); console.log(tr("{{h}} {{w}}!", {h:"Hello"}, {w:"world"})); 

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