need to grab from 2 arrays in javascript - javascript

My arrays:
var mexicanFood = ["Taco Bell", "Beans", "Taco Time", "Buritos", "Chalupa"];
var asianFood = ["Noodles", "Rice", "Sushi", "Fish", "Chicken"];
var americanFood = ["Hot dogs", "Pizza", "Burgers", "Nachos", "Other"];
Know this is a possibility to grab randomly from array:
var randomIndex = Math.floor(Math.random() * mexicanFood.length);
I want to pull a value from each food category. I don't want all of mexicanFood values to be the result for food options. I want it at random but at least to pull one or two from each category. How can you do that with having it go into radio buttons (maybe 5 radio buttons) and can it be done with Math.random?
Also want it to be in javascript and html if possible
Edit:
I basically want different food categories in arrays. Then have random values pulled from the categories and those values will be put into radio buttons. My overall project that I want to create is a voting poll for restaurants to eat at. So I don't want 5 burger places to come up when I have mexican, asian, american, and other options to randomly pull from.
What I am stuck on is how to randomly pull from each array. I know how to randomly pull from one array list. But when I have mexicanFood, asianFood and americanFood (or even more than those), I am not sure how to randomly pull values from those and have those values populate radio buttons

I'm assuming you want to return an array of random foods, containing at least 1 from each category.
I've created a function called createRandomArray(), which accepts an arraySize. This arraySize refers to the amount of items you wish to have in your final array.
In the function, I'm concatenating all of the food arrays together. I'm then looping through this array to add a random index to a new array.
var mexicanFood = ["Taco Bell", "Beans", "Taco Time", "Buritos", "Chalupa"],
asianFood = ["Noodles", "Rice", "Sushi", "Fish", "Chicken"],
americanFood = ["Hot dogs", "Pizza", "Burgers", "Nachos", "Other"];
function createRandomArray(arraySize) {
var allFoods = mexicanFood.concat(asianFood).concat(americanFood),
randomFoods = [];
if (arraySize <= allFoods.length) {
randomFoods = [
mexicanFood[getRandomArrayIndex(mexicanFood)],
asianFood[getRandomArrayIndex(asianFood)],
americanFood[getRandomArrayIndex(americanFood)]
]; // at at least one from each
// remove the ones that were initially added from each
allFoods.splice(allFoods.indexOf(randomFoods[0]), 1);
allFoods.splice(allFoods.indexOf(randomFoods[1]), 1);
allFoods.splice(allFoods.indexOf(randomFoods[2]), 1);
for (var i = 0; i < arraySize - 3; i++) {
var randomIndex = getRandomArrayIndex(allFoods);
randomFoods.push(allFoods[randomIndex]);
allFoods.splice(randomIndex, 1);
}
return randomFoods;
}
return allFoods; // requesting more items of food than the amount available, so just add them all
}
function getRandomArrayIndex(array) {
return Math.floor(Math.random() * array.length);
}
var randomFoods = createRandomArray(5);
for (var i = 0; i < randomFoods.length; i++) {
document.getElementById('food-form').innerHTML += '<input type="radio" name="food" value="' + randomFoods[i] + '"> ' + randomFoods[i] + '<br>';
}
<form action="" id="food-form"></form>

Related

Randomly grab 3 items from an array, where the 3rd item can be a “restaurant" but does not have to be

I apologize for the poorly written title. I was not sure how exactly to write it. I have an array. I need to randomly grab three items from the array. Only one item can be a "restaurant" and the restaurant can ONLY ever go in the third position.
Let me explain with an example. here is a sample array
el 1 - restaurant = false
el 2 - restaurant = true
el 3 - restaurant = true
el 4 - restaurant = false
el 5 - restaurant = false
el 6 - restaurant = false
el 7 - restaurant = true
el 8 - restaurant = false
el 9 - restaurant = false
My current code loops through this array and randomly grabs three items. Positions 1 and 2 can NEVER have a restaurant in them so they have to be taken from the items with the restaurant property set to false. The 3rd position can have a restaurant but I don't want it to always be a restaurant.
Here is my current code:
const amountOfLocations = 3
// have list of locations
// shuffle it
for (let i = locations.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[locations[i], locations[j]] = [locations[j], locations[i]];
}
let selectedLocations = locations.slice(0, amountOfLocations)
My initial thought is I need to grab only 2 items from this current loop instead of 3, then using the original array remove these two items and shuffle the array up again to randomly grab one more item which will then be placed in the 3rd position.
You could continue using the shuffle method so you don't end up selecting duplicates like with plain random indexing, then you just extract the first element from the shuffled array and call it "third". Then you filter out non-restaurants (and slice the first index before because we've already selected it) and select any 2 elements:
for (let i = locations.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[locations[i], locations[j]] = [locations[j], locations[i]];
}
let third = locations[0];
let [first, second] = locations.slice(1).filter(l => !l.restaurant);
let selectedLocations = [first, second, third];
Use a whole loop. randomly select an element — if you are not choosing the third element and a restaurant is picked, don’t save the choice and let the whole loop run again (until you have three elements).
Or
Make a temporary array without the restaurants in it, and then randomly select from that array twice. Then randomly select from the normal array. If it matches one of the two you already have, then get it again (use a while loop).
You can try something like this.
var array1 = [
{'restaurant': true},
{'restaurant': false},
{'restaurant': false},
{'restaurant': true},
{'restaurant': false},
{'restaurant': true},
{'restaurant': false},
{'restaurant': false},
{'restaurant': false},
{'restaurant': false},
{'restaurant': true}
];
var array2 = array1.filter((v) => {
return v.restaurant === false;
}).slice(0, 2);
array2.push(array1[Math.floor(Math.random() * array1.length)]);
console.log(array2);
Here's a link to fiddle. https://jsfiddle.net/90gda2sb/
const third = shuffledArray[0]
const [first, second] = first two no-resturant item in shuffledArray.slice(1)

Making a Search Filter with JQuery?

So I have a Table made from some json data...
{
"AKH":{
"name": "Amonkhet",
"code": "AKH"
"cards": [
{
"artist": "Izzy",
"cmc": 3,
"colorIdentity": [
"W"
],
"colors": [
"White"
],
"id": "df3a6e0336684c901358f3ff53ec82ff5d7cdb9d",
"imageName": "gideon of the trials",
"layout": "normal",
"loyalty": 3,
"manaCost": "{1}{W}{W}",
"multiverseid": 426716,
"name": "Gideon of the Trials",
"number": "14",
"rarity": "Mythic Rare",
"subtypes": [
"Gideon"
],
"text": "+1: Until your next turn, prevent all damage target permanent would deal.\n0: Until end of turn, Gideon of the Trials becomes a 4/4 Human Soldier creature with indestructible that's still a planeswalker. Prevent all damage that would be dealt to him this turn.\n0: You get an emblem with \"As long as you control a Gideon planeswalker, you can't lose the game and your opponents can't win the game.\"",
"type": "Planeswalker — Gideon",
"types": [
"Planeswalker"
]
},
The Table row ends up looking like this for each of the cards. at the moment I only Attach the ID, Card name, and Mana Cost to each row
<td><a href="#" onclick="showInfo(this.id)"
id="df3a6e0336684c901358f3ff53ec82ff5d7cdb9d">Gideon of the Trials</a></td>
Now I want to search through these cards. (Keep in mind there are over 17,000 different cards that will be on this list) I can get it to find the things.. But I'm having several different issues... Either it finds them all but doesn't hide the rest of the list, or it hides the whole list and only displays one of the found cards.
So question A... What am I missing to make the search work correctly?
$(document).on('change', 'input[type=checkbox]', function() {
var lis = $('.cardsRow')
$('input[type=checkbox]').filter(':checked').each(function(){
filterKeyB = $(this).attr('id')
filterKeyA = $(this).attr('name')
$.each(json, function(setCode, setListing) {
$.each(setListing.cards,function(cardNum, cardListing){
var x = Object.keys(cardListing)
var y = Object.keys(cardListing).map(function (key){
return cardListing[key]
})
for (i = 0; (i < x.length); i++) {
if(x[i] === filterKeyA){
if (y[i] instanceof Array){
var holder = y[i]
var valueArr =[]
for(var k = 0; k < holder.length; k++){
valueArr = holder.join('|').toLowerCase().split('|')
var foundIt = valueArr.includes(filterKeyB)
}
}else{
var stringy = y[i]
var stringyA= stringy.toLowerCase().replace(/\s/g, '')
if (stringyA === filterKeyB){
var foundIt = true
}
}
if(foundIt === true){
$winner = cardListing.name
for (k = 0; (k < lis.length); k++){
if (lis[k].innerText.indexOf($winner) != -1) {
$(lis[k]).show()
}
}
}
}
}
})
Question B... Since you are already here... Would it be better practice to attach the data that can be searched to the element itself? Maybe just the most searched (Like Name and Mana) and have more advanced queries go through the data again?
I don't understand why the code isn't working or even how it works, it looks like it references some functions that aren't defined in the sample. But I can share with you a really simple/intuitive way to filter stuff, I hope you find it useful.
Native filter method is so useful for what you're trying to do, it takes a callback that takes current element as an arg and returns true or false, if true, the element is included in the new array it produces.
But filter only takes one function, and you have many filters, so let's make a function that combines many filter Fns together into one fn, so you can pass them in all at once:
const combineFilters = (...fns) => val => fns.reduce((prev, curr) => prev || curr(val), false);
OK, how about storing the names of the filter functions as keys in an object so we can reference them using a string? That way we could give each checkbox an ID corresponding to the name of the filter function they are supposed to apply, and makes things really easy to implement (and read):
const filterFns = {
startsWithG(card) {
return card.name[0] === 'G';
},
//etc.
};
OK, time to get the IDs of all the checkboxes that are clicked, then map them into an array of functions.
const filters = $('input[type=checkbox]')
.filter(':checked')
.map((e, i) => $(i).attr('id'))
.get()
.map(fnName => filterFns[fnName])
(Assume the relevant data is stored in a var called...data.) We can use combineFilters combined with filters (array of Fns) to activate all of the relevant filters, then map the resulting array of matching objects into the HTML of your choosing.
const matches = data.cards
.filter(combineFilters(...filters))
.map(card => `<div>${card.name}</div>` );
Then time to update DOM with your matches!
As others have noted, if you need to do any more complicated filtering on objects or arrays, lodash library is your friend!

How do I create a random property inside a randomly selected object?

For example, if I have:
var weapon = [ "sword", "mace", "staff"];
var swordtype = [ "long", "short"];
var stafftype = [ "quarter", "magic"];
and my script randomly selects 'Sword' to display in my HTML p tag from the weapon variable.
How can I say that if my code randomly selects "Sword" from the weapon variable, it will also randomly select a "swordtype" to go with it? Making the output either "long sword" or "short sword"?
You'll need to associate related data. So, your structure could be like this:
// Use objects, not arrays to store key/value pairs
var weapons = {
sword:["long","short", "broad"],
mace: ["standard", "long", "short"],
staff: ["quarter", "magic", "wizard"],
"nuclear missle": ["10 megaton", "20 megaton", "50 kiloton"],
dagger: ["standard", "poison"]
};
// Function for selecting random weapon
function getRandomWeapon(){
// Choose random weapon as an index from the weapons object:
var weaponNum = Math.floor(Math.random() * Object.keys(weapons).length);
// Get the property name that corresponds to that key number:
var weapon = Object.keys(weapons)[weaponNum];
// Choose random weapon type as an index from the random weapon selected above:
var specificWeaponNum = Math.floor(Math.random() * weapons[weapon].length);
// Get the array value associated with that index
var specifcWeapon = weapons[Object.keys(weapons)[weaponNum]][specificWeaponNum];
return specifcWeapon + " " + weapon;
}
document.querySelector("button").addEventListener("click", function(){
document.getElementById("weapon").textContent = getRandomWeapon();
});
<div>You have a: <span id="weapon"></span></div>
<button>Get Weapon</button>

Generating a price per item in an html table using a javascript

I have a javascript that is generating a table for me. The elements in the table are gathered in an array of arrays called sep. Sep contains 1152 sub arrays that are of the form:
Sep[0] //["316SS", "K", "-100 to 225°C", "Brass", "1/8", "4'", "4'", "8", "Ungrounded"]
So basically there are 1152 rows, each of which defines a products with 9 parameters. I want to make a for-loop that will create a price for each of the configurations. This is what I have so far:
//PART 1-------------WORKS FINE-----------------------------------
var eopartprice2 = []; //matrix that I want to contain my prices
for (var i = 0; i < sep.length; i++) {
strnum1 = sep[i][5]; //parameter 5 is a length of material
len1 = Number(strnum1.substr(0, strnum1.length - 1));
strnum2 = sep[i][6]; //parameter 6 is another length of material
len2 = Number(strnum2.substr(0, strnum2.length - 1));
strnum3 = sep[i][7]; //parameter 7 is the number of units required
condnum = Number(strnum3.substr(0, strnum3.length));
feetOfMat = len1*len2*condnum; //The product of these is the total feet of req material
//PART 2------------PFCost always = 0.87--------------------------
//Next i need to identify the cost of the material (to multiply by the total feet)
var costOfMat = [0.87, 0.87, 1.77, 0.55] //different costs of the 4 materials
if (sep[i][0] = "304SS") {
var PFCost = costOfMat[0]; //304SS costs 0.87/foot
} else if (sep[i][0] = "316SS") {
var PFCost = costOfMat[1]; //316SS costs 0.87/foot
} else if (sep[i][0] = "Inconel") {
var PFCost = costOfMat[2]; //Inconel costs 1.77/foot
} else if (sep[i][0] = "High Temp. Glass") {
var PFCost = costOfMat[3]; //High Temp. Glass costs 0.55/foot
}
baseMatCost[i] = PFCost*feetOfMat; //I'd like to generate a matrix that
//contains all of the base prices (1 for each row)
//PART 3---------------fitcost always = 36------------------------
//Trying to identify the cost of brass vs. stainless fittings
if (sep[i][3] = "Brass") {
fitcost = 36;
} else if (sep[i][3] = "Stainless Steel") {
fitcost = 37;
}
}
My Problem so far is that I want the prices to be defined based off of whether or not the if statements are satisfied but in both cases (fitcost and PFCost) the values are simply the ones defined in the first if statement.
Lastly I'd like to generate my final price in the eopartprice2 matrix based off adding up the materials generated above + some cost of labor multiplied by some margin.
Also I'm concerned with the speed of how quickly this runs as it will be a live table in my website, and every time I add more to this I feel like it's taking longer and longer to generate. Here's a link to my w3 that I'm working in.
Please, any help would be greatly appreciated :)
In your if statement conditions, you're using a single equals sign. This is an assignment operator, not a comparison operator!
So, an if statement such as if (sep[i][0] = "304SS") is actually assigning the value "304SS"; it is not comparing the value "304SS" to sep[i][0].
To correctly compare the values, you'll want to change the single equals sign to a double equals:
if (sep[i][0] == "304SS").
Note: == will convert types if necessary before comparing. For example: ".87" == 0.87 returns true.

Extract int value in index array?

So I have a question about this score table I made in html.
var puntenTelling= new Array(3,4,2,1,5);
var teamNamen = new Array(puntenTelling[0]+"Team1", puntenTelling[1]+"Team2",puntenTelling[2]+ "Team3", puntenTelling[3]+"Team4", puntenTelling[4]+"Team5");
puntenTelling.sort(function(a, b){return b-a});
teamNamen.sort();
teamNamen.reverse();
for (var i=0; i<5; i++) {
document.write("<tr><td>" + teamNamen[i]);
document.write("<td>" + puntenTelling[i] + "</td></tr>");
}
Basically this gives me a sorted table, which is sorted on points, and sorted on the teamnames linked to the points.
I have to include the points (puntenTelling) in the array of the teamNames since otherwise I can't sort it in the same way I can sort the points.
Now I am printing it out like this:
Teamname Points
5Team5 5
4Team2 4
3Team1 3
2Team3 2
1Team4 1
I would just like to get rid of the "5,4,3,2,1"
before the "Team5,Team2" etc.
How can I do this?
Your approach of concatenating points and team names is not very clean and robust (how about a team named 1860 Munich?) Much better would be to make an array of objects that contain both team name and its points, and work with this array:
var teamsWithPoints = [
{ name: "team1", points: 3 },
{ name: "team2", points: 4 },
{ name: "team3", points: 2 },
{ name: "team4", points: 1 }
];
teamsWithPoints.sort(function(a, b) { return b.points - a.points });
document.write("<table>");
teamsWithPoints.forEach(function(team) {
document.write("<tr>");
document.write("<td>" + team.name);
document.write("<td>" + team.points);
});
Seems to me that you need a dictionary (associative array) where the keys represent the team's order in the list. Sort the array by the keys, then just print the values. It could even be multidimensional where the key is the desired ranking position and the value contains the team name and the points.
When you're making the array, you're creating objects like this.
var teamNamen = new Array(puntenTelling[0]+"Team1", puntenTelling[1]+"Team2",puntenTelling[2]+ "Team3", puntenTelling[3]+"Team4", puntenTelling[4]+"Team5");
If you don't want the value to be included in the string value, you'd declare teamNamen like so.
var teamNamen = new Array("Team1", "Team2","Team3","Team4","Team5");
However, this will make your original sort not function properly. So you could try this following code to maintain the proper sorting functionality, while printing the correct value.
for (var i=0; i<5; i++) {
document.write("<tr><td>" + teamNamen[i].substring(1));
document.write("<td>" + puntenTelling[i] + "</td></tr>");
}

Categories

Resources