Home > Enterprise >  How to replace placeholder in string with different value if more placeholders exist?
How to replace placeholder in string with different value if more placeholders exist?

Time:12-24

arr = [1,2,3,4,5,6,7]
val = ? (3 different values from arr)
result = "${val} and ${val} and ${val}"

I want to replace ${val} with arr elements such that ${val} will not be same in result.

I seriously don't have idea how to replace different values in place of ${val}

CodePudding user response:

Another idea is to make val a function that would return an element of the arr.

I used a tempArr to avoid mutating the original arr.
When there is no more values to use... It will return ?.

const arr = [1, 2, 3, 4, 5, 6, 7];
let tempArr = [...arr]

val = () => {
  
  if(!tempArr.length){
    return '?'
  }
  const randomIndex = Math.floor(Math.random() * tempArr.length)
  const arrElement=  tempArr[randomIndex];
  tempArr.splice(randomIndex, 1)
  
  return arrElement
};

console.log(`${val()} and ${val()} and ${val()}`);
console.log(`${val()} and ${val()} and ${val()}`);
console.log(`${val()} and ${val()} and ${val()}`);

CodePudding user response:

Here's my approach:

Use a tagged template literal to change the processing of the arguments to suit your needs.

The ? in your question (val = ?) is simply a copy of the array using [...arr]. Then, the tag function will call a randomElement function on the argument. This function will randomly remove and return one of the elements from the array.

function randomElement(array) {
  if (!array) return array;
  return array.splice(Math.floor(Math.random() * array.length), 1);
}

function rand(strings, ...args) {
  const parts = [];
  for (let string of strings) {
    parts.push(string, randomElement(args.shift()));
  }
  return parts.join('');
}

arr = [1, 2, 3, 4, 5, 6, 7]
val = [...arr]
result = rand`${val} and ${val} and ${val}`
console.log(result);

CodePudding user response:

What you're likely looking for is array shuffling. This thread contains some useful functions for it: https://stackoverflow.com/a/2450976/13199472 (personally, I like using the ES6 variant of Durstenfeld shuffle algorithm, which is the second answer in that thread).

With the shuffle function available, your code should look something like this:

arr = [1,2,3,4,5,6,7]
shuffle(arr)
result = `${arr[0]} and ${arr[1]} and ${arr[2]}`

There is no need for a separate variable. However, since you mentioned your dataset contains strings where template tags have the same name, a possible solution would be to not treat the string as a JavaScript template literal, but rather, a plain string in which you will replace tags individually.

let arr = [1,2,3,4,5,6,7]
shuffle(arr)

// notice how these are STRINGS, not template literals, they
// are inside single quotes, not backticks
// using backticks here will break your code

const template = '${val} and ${val} and ${val}'
const tagCount = template.split('${val}').length

let output = template;

for (let i = 0; i < tagCount; i  ) {
    output = output.replace('${val}', arr[i])
    // you can take arr[i % arr.length] instead of arr[i]
    // in case you have more tags than items in the array, but
    // this will obviously result in duplications
}

String.prototype.replace will only ever replace the first occurrence of the provided string, so this approach will allow you to replace each tag one by one with an item from the shuffled array.

  • Related