Jordi Nebot
Jordi Nebot

Reputation: 3401

Keep N occurrences of a single character in a string in Javascript

Let's say I have this string: "a_b_c_d_restofthestring" and I only want to keep (e.g.) 2 underscores. So,

 "a_b_cdrestofthestring"
 "abc_d_restofthestring"

Are both valid outputs.

My current implementation is:

let str = "___sdaj___osad$%^&*";

document.getElementById('input').innerText = str;

let u = 0;
str = str.split("").reduce((output, c) => {
  if (c == "_") u++;
  return u < 2 || c != "_" ? output + c : output;
});

document.getElementById('output').innerText = str;
<div id="input"></div>
<div id="output"></div>

But I'd like to know if there's a better way...

Upvotes: 1

Views: 73

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386604

You could take a regular expression which looks for an underscore and a counter of the keeping underscores and replace all others.

var string = "a_b_c_d_restofthestring",
    result = string.replace(/_/g, (c => _ => c && c-- ? _ : '')(2));
    
console.log(result);

Upvotes: 2

p.s.w.g
p.s.w.g

Reputation: 149020

Your code seems to work fine, but here's a one-liner regular expression that replaces all but the last two underscores from the input string.

let input = "___sdaj___osad$%^&*";
let output = input.replace(/_(?=(.*_){2})/g, '');

console.log("input: " + input);
console.log("output: " + output);

This of course is not very generalized, and you'd have to modify the regular expression every time you wanted to say, replace a character other than underscore, or allow 3 occurrences. But if you're okay with that, then this solution has a bit less code to maintain.


Update: Here's an alternate version, that's fully generic and should perform a bit better:

let input = "___sdaj___osad$%^&*";

function replace(input, char = '_', max = 2, replaceWith = '') {
  let result = "";
  const len = input.length;
  
  for (let i = 0, u = 0; i < len; i++) {
    let c = input[i];
    result += (c === char && ++u > max) ? replaceWith : c;
  }
  
  return result;
}

console.log("input: ", input);
console.log("output: ", replace(input));

See this jsPerf analysis.

Upvotes: 2

Related Questions