-2
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}

trincot
  • 317,000
  • 35
  • 244
  • 286
ABHAY
  • 1
  • 2
  • Basically, I want result = "2 and 4 and 7" or result = "1 and 3 and 6". So, numbers should be random and non repeated. – ABHAY Dec 23 '22 at 19:59
  • it should be random. Many Permutation and combination possible. – ABHAY Dec 23 '22 at 20:00
  • So your question is: how can I randomly take three distinct values from an array and print them with the word "and" between them? – trincot Dec 23 '22 at 20:01
  • and I want to replace it with template literal having ${val} as placeholder – ABHAY Dec 23 '22 at 20:02
  • That's my question, how to define val such that it will have 3 different numbers for result = `${val} and ${val} and ${val}` – ABHAY Dec 23 '22 at 20:13
  • Actually I am working on a project in which I have a dataset already provided to me with only one ${val} everywhere and I have to find different values of val. – ABHAY Dec 23 '22 at 20:16
  • Well not possible to do it the way you want, you need to alter the template string. – epascarello Dec 23 '22 at 20:17
  • dataset is in the form of string like: "${name} and ${name} welcome !". – ABHAY Dec 23 '22 at 20:19
  • What about calling a function something like `\`${fn()} and ${fn()} and ${fn()}\`` where `fn` [gets a random element from the array](https://stackoverflow.com/questions/4550505/getting-a-random-value-from-a-javascript-array)? – Wyck Dec 23 '22 at 20:20
  • My objective is to find name such that for two repetitions it will have different names. – ABHAY Dec 23 '22 at 20:20
  • No I can't use functions because I am provided with strings "${name} and ${name} welcome !". – ABHAY Dec 23 '22 at 20:21
  • One approach I am thinking, if I could break this array and then run a loop and add a name. And after all iterations, concatenating the array – ABHAY Dec 23 '22 at 20:23
  • Okay, So let me again try to explain. I am provided with a string, for example: result= "${name} and {name} Welcome!". And I have an array of names. My objective is to get a string for example, "Elon and Bill Welcome". So, what I am doing is, I am getting a random name from array and using eval(" ` "+result+" ` "). But here what's happening, I am getting result as "Elon and Elon Welcome". But I want next name to change its value. – ABHAY Dec 23 '22 at 20:33
  • Sure, but you should edit your question now, because you presented this as a template literal related problem, and it isn't. There is no template literal here. There is a string with braces where you want to make replacements. Nothing to do with template literal. Please edit your question's title, code, tag, ...etc to remove anything that mentions or uses template literals. – trincot Dec 23 '22 at 20:40
  • OK, I did the edit for you. Please check. I will now remove my comments, since they dealt with a previous version of your question. – trincot Dec 23 '22 at 20:43
  • My answer deals with the previous version (using template litterals, not placeholders in a string). – Louys Patrice Bessette Dec 23 '22 at 20:45
  • Okay, Now, I got the solution. Thanks a lot. You al have cleared all my doubts related to template literals and strings. Thank you so much!!! – ABHAY Dec 23 '22 at 20:55
  • Would you mind checking the best answer as accepted (green check mark)? – Louys Patrice Bessette Dec 23 '22 at 21:42

3 Answers3

0

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()}`);
Louys Patrice Bessette
  • 33,375
  • 6
  • 36
  • 64
-1

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.

  • 1
    I think that's an awesome approach. I will try this. Thanks a lot !!! – ABHAY Dec 23 '22 at 20:38
  • I think the tagged template literal approach posted by Wyck is also really nice, it's technically the modern way to do it, but if you're a beginner, you might want to read more about them [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) to get a better understanding of how they work. – József Sallai Dec 23 '22 at 20:44
-1

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);
Wyck
  • 10,311
  • 6
  • 39
  • 60