1

I need to replace thousands of #FFF instances in the string via

Math.floor(Math.random()*16777215).toString(16)

The problem I ran into is that I'm unable to make JS to run this command for each #FFF in the string, instead, it replaces all #FFF to a single result.

var string = '1677px 335px #FFF , 59px 1161px #FFF , 850px 963px #46f3b8';
var randomColor = string.replace(/#FFF/g, "#"+Math.floor(Math.random()*16777215).toString(16));
console.log(randomColor);

results in something like:

1677px 335px #46f3b8 , 59px 1161px #46f3b8 , 850px 963px #46f3b8
FZs
  • 16,581
  • 13
  • 41
  • 50
Imforpeace
  • 177
  • 10
  • 2
    Use a [callback function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Using_an_inline_function_that_modifies_the_matched_characters) instead of a value for the replacement argument – Nick Parsons Aug 01 '20 at 14:04
  • `.replace(/#FFF/g, ()=>"#"+Math.floor(Math.random()*16777215).toString(16))` – user120242 Aug 01 '20 at 14:05
  • 1
    Does this answer your question? [Typescript/Javascript: Replace All String Occurrences with Random Number](https://stackoverflow.com/questions/43504533/typescript-javascript-replace-all-string-occurrences-with-random-number) – user120242 Aug 01 '20 at 14:09

2 Answers2

2

I like the approach of splitting your string, then iterating and joining together using unique values:

var string = '1677px 335px #FFF , 59px 1161px #FFF , 850px 963px #FFF , 333px 496px #FFF , 704px 507px #FFF';
var parts = string.split("#FFF");
var output = parts[0];
for (i=1; i < parts.length; ++i) {
    output += "#" + Math.floor(Math.random()*16777215).toString(16) + parts[i];
}
console.log(string);
console.log(output);
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • Is there any particular reason this is better than the `.replace` one? – Ayush Gupta Aug 01 '20 at 16:12
  • No. It's just a different way of expression that some people might prefer. Using split and join to delimit and generate strings is a common operation, so it meshes well with manipulation of a list of style color codes to generate a string well logically. FYI this code could be done with one line with chained manipulation in a way that is much easier to read IMO. `split.map(x=>random).join` would IMO far more concise and clear than this simple concat loop. But that's a matter of opinion. – user120242 Aug 01 '20 at 16:28
2

The problem is, that in your code,

'#' + Math.floor(Math.random()*16777215).toString(16)

is evaluated once, then its result string is passed to replace, and it replaces all occurrences of #FFF with that string.

Instead, you can use a function as a replacer, that is called for each match and can generate different values:

var string = '1677px 335px #FFF , 59px 1161px #FFF , 850px 963px #46f3b8';
var randomColor = string.replace(/#FFF/g, () => '#' + Math.floor(Math.random()*16777215).toString(16));
console.log(randomColor);
FZs
  • 16,581
  • 13
  • 41
  • 50