BKS
BKS

Reputation: 2333

Changing variable in Java Script

in JS, I have a list of variables, which I shuffle. I want to maintain the order of the shuffle, but change the values of the variables in the list. Is there a way to do that? Below is an example of my code. I explain what I want in the comments.

<p id="demo"></p>

<script>
var gen = "male "
var race = "white "
var rel = "christian "

var chars =[gen,race,rel]
chars = shuffle(chars); 

document.getElementById("demo").innerHTML = chars+"";

/*prints for example "white christian male " which is what I want

/*lets say I want to change the gender, and maintain the newly shuffled order (race-rel-gen in this case)*/ 

/* The below doesn't work. I want it to print "white christian female ", but it just reprints the original string*/

gen = "female "

document.getElementById("demo").innerHTML = chars+"";
</script>

Upvotes: 0

Views: 167

Answers (6)

Daanist
Daanist

Reputation: 26

You should define a shuffle function. Something like this:

// define shuffle function
function shuffle(arr) {
  for (let i = arr.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [arr[i], arr[j]] = [arr[j], arr[i]];
  }
  return arr;
}

Then you can call this function with chars as a param to create a shuffled array like this:

var chars = [gen, race, rel];

You can then output the result as a string like this:

document.getElementById("demo").innerHTML = shuffle(chars).join(" ");

The join(" ") to replace the comma with an space.

option 1) reshuffle with new value(s)

As your original chars array's order doesn't shuffle, you can change the value's by doing this:

chars[0] = "female";

You can update the DOM by calling the shuffle function again as shown above.

option 2) keep the shuffled order en output it with an updated value

To keep the shuffled order, but output the array again with an updated value, you need to store the shuffled output in a new variable. You will get something like this:

var chars = [gen, race, rel];
var shuffled = shuffle(chars);

document.getElementById("demo").innerHTML = shuffled;

// change value of gen
shuffled[shuffled.indexOf("male")] = "female";

// output again
document.getElementById("demo").innerHTML = shuffled;

Upvotes: 0

zfrisch
zfrisch

Reputation: 8660

You can use a map object and some supplemental functions to take care of this.

let char = new Map([
  ['gen', 'male'],
  ['race', 'white'],
  ['rel', 'christian'],
  ["order", shuffle([0,1,2])],
  ["display", ['gen', 'race', 'rel']]
]);

function shuffle(arr) {
  return arr.sort(_ => Math.random() > .5);
}

function display(mItm) {
return mItm.get("order").map(itm => mItm.get(mItm.get("display")[itm])); 
}

//display char
document.querySelector("#demo").innerHTML += "</br>" + display(char);

//display new race
char.set("race", "blue");
document.querySelector("#demo").innerHTML += "</br>" + display(char);

// reshuffle
char.set("order", shuffle(char.get("order")));
document.querySelector("#demo").innerHTML += "</br>" + display(char);
<p id="demo"></p>

Upvotes: 2

luiscrjr
luiscrjr

Reputation: 7268

Considering you want to maintain the pre-shuffled order, you can try to use an object, instead of string, then it'll keep reference. Something like this:

/* function to convert your array of objects into a pretty string */
const arrtoStr = (arr) => arr.map((obj) => obj.value).join(' ')

var gen = { value: "male" }
var race = { value: "white" }
var rel = { value: "christian" }

var chars =[gen,race,rel]
chars = shuffle(chars); 

//will output, for instance: "white christian male"
document.getElementById("demo").innerHTML = arrtoStr(chars);

// change object's key named 'value'
gen.value = "female"

//will output: "white christian female"    
document.getElementById("demo").innerHTML = arrtoStr(chars);

Upvotes: 2

jackrugile
jackrugile

Reputation: 1663

If I understand correctly, the solution below should work. Keeping a person object and an order array separate should give you more flexibility. I am using Lodash for shuffle as a convenience.

CodePen Demo

this.person = {
 gen: "male",
 race: "white",
 rel: "christian"
};

this.order = ["gen", "race", "rel"];

function output() {
  let temp = [];
  this.order.forEach((key) => {
    temp.push(this.person[key]);
  });
  document.getElementById("demo").innerHTML += temp.join(", ") + "<br>";
}

// shuffle the order of properties
_.shuffle(this.order);

// output original data
output();

// change specifics, but keep the order of properties
this.person["gen"] = "female";
output();

this.person["race"] = "black";
output();

this.person["rel"] = "jewish";
output();

Upvotes: 1

marmeladze
marmeladze

Reputation: 6564

You, possibly asked wrong question, or, your original intentions are not reflected in question, but as far as I understand, you are looking for sth like that.

var races = ["caucasian", "ethiopian", "malayan", "american", "mongolian"];
var beliefs = ["jewish", "buddhist", "muslim", "christian", "shintoist"];
var genders = ["male", "female"];

var randomArrayElement = function(arr) {
  return arr[Math.floor(Math.random() * arr.length)];
}

function makeCombo(r, b, g) {
  var race = randomArrayElement(r);
  var belief = randomArrayElement(b);
  var gender = randomArrayElement(g);
  return [race, belief, gender].join(" ");
}

document.querySelector("button").addEventListener("click", function(e){
  document.getElementById("profile-area").innerText = makeCombo(races, beliefs, genders);
})
<p id='profile-area'></p>
<button>Generate a profile</button>

Upvotes: 0

AndrewL64
AndrewL64

Reputation: 16311

You can either assign the array again after assigning the new variable value like this:

var gen = "male "
var race = "white "
var rel = "christian "

var chars =[gen,race,rel]
chars = shuffle(chars); 

document.getElementById("demo").innerHTML = chars+"";


gen = "female "
var chars =[gen,race,rel]
chars = shuffle(chars); 
document.getElementById("demo").innerHTML = chars+"";

jsFiddle: https://jsfiddle.net/AndrewL64/p6rgo01a/


Or create a reusable function like this:

function newVal(gen, race, rel) {
    var chars =[gen,race,rel]
    chars = shuffle(chars);
    document.getElementById("demo").innerHTML = chars+"";
}

newVal('male ','white ', 'christian ');

newVal('female','white ', 'christian ');

jsFiddle: https://jsfiddle.net/AndrewL64/p6rgo01a/1/

Upvotes: 0

Related Questions